【问题标题】:Conversion of custom init routines in SwiftSwift 中自定义初始化例程的转换
【发布时间】:2014-06-30 16:58:29
【问题描述】:

我需要继承 SVModalWebViewController.m (GitHub) 的子类,它本身就是 UINavigationController 的子类,并将此代码合并到将完全在 Swift 中创建的新应用程序中。我遇到了几个问题,所以我决定首先将这个非常简单的类转换为 Swift 进行调试。

与 Objective-C (read more about Swift initialization here) 相比,Swift 中的初始化略有不同,这就是为什么我没有在 Swift 代码中返回 self

这是原始的 Obj-C 代码(减去 *.h,它实例化 barsTintColor):

#import "SVModalWebViewController.h"
#import "SVWebViewController.h"

@interface SVModalWebViewController ()

@property (nonatomic, strong) SVWebViewController *webViewController;

@end


@implementation SVModalWebViewController

#pragma mark - Initialization


- (id)initWithAddress:(NSString*)urlString {
    return [self initWithURL:[NSURL URLWithString:urlString]];
}

- (id)initWithURL:(NSURL *)URL {
    self.webViewController = [[SVWebViewController alloc] initWithURL:URL];
    if (self = [super initWithRootViewController:self.webViewController]) {
        UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                    target:self.webViewController
                                                                                    action:@selector(doneButtonClicked:)];

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
            self.webViewController.navigationItem.leftBarButtonItem = doneButton;
        else
            self.webViewController.navigationItem.rightBarButtonItem = doneButton;
    }
    return self;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];

    self.webViewController.title = self.title;
    self.navigationBar.tintColor = self.barsTintColor;
}

@end

这是该类的整个 Swift 版本(我简化为只有一个 init 方法,因为我不需要专门使用 URL 进行初始化):

import UIKit

class SVModalWebViewController: UINavigationController {
    var webViewController: SVWebViewController!
    var barsTintColor: UIColor?

    // This was added because of a compiler error indicating it needed to be added
    init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    init(address urlString: String!) {
        let url: NSURL = NSURL.URLWithString(urlString)
        self.webViewController = SVWebViewController(URL: url)
        super.init(rootViewController: self.webViewController)

        let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self.webViewController, action: Selector("doneButtonClicked:"))

        if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
            self.navigationItem.leftBarButtonItem = doneButton
        } else {
            self.navigationItem.rightBarButtonItem = doneButton
        }
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        // self.title may not be set, and is considered an optional in Swift, so we have to check first
        if self.title {self.webViewController.title = self.title}
        self.navigationBar.tintColor = self.barsTintColor
    }
}

我遇到的问题与在navigationItem 中设置Done 按钮有关。目前,当调用此代码时,它们根本没有出现:

let webViewController = SVModalWebViewController(address: "http://www.google.com");
webViewController.barsTintColor = UIColor.blueColor()
self.presentModalViewController(webViewController, animated: true)

模态视图看起来很好,我能够正确设置条形颜色属性,但Done 按钮没有显示。看来我没有正确访问UINavigationControllernavigationItem 的权限。请注意,由于没有它的编译器错误,我必须使用 nibName 方法添加 init。这在 Obj-C 代码中不是必需的,我承认我不确定为什么在 Swift 中需要它——这可能是问题的一部分。

关于为什么我不能设置UINavigationControllerself.navigationItem.leftBarButtonItem 属性有什么想法吗?谢谢!

【问题讨论】:

    标签: objective-c uinavigationcontroller initialization swift uinavigationitem


    【解决方案1】:

    UINavigationController 没有navigationItem。嗯,确实有,但是没用。导航栏中显示的是子控制器的navigationItem(在本例中为rootViewController,您也将其称为self.webViewController)。

    【讨论】:

    • 你是对的。我最初有“self.webViewController.navigationItem.leftBarButtonItem = doneButton”,但在调试时取出了“webViewController”。当我添加 'webViewController' 时,我得到了 'can't unwrap Optionals.None' 错误。鉴于我没有实例化 navigationItem 并且实际上是在此处设置它(我已经知道它是 nil),我该如何解决这个错误?
    • 是的,我已经将 很多 代码从 Objective-C 翻译成 Swift,我发现这样的错字非常非常容易。
    • 那大概是因为你没有webViewController。但实际上,那将是一个不同的问题。我回答了(我相信是正确的)你提出的问题。
    • 谢谢。但到那时我不应该有一个吗?我在类的顶部调用 var webViewController: SVWebViewController! 并在 init 中使用 self.webViewController = SVWebViewController(URL: url) 实例化它,在相关代码之前。
    • 显然初始化器返回 nil。我对 SVWebViewController 一无所知,所以我不知道(或关心)为什么会这样。
    猜你喜欢
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2020-06-26
    相关资源
    最近更新 更多