swift – 合并视图而不是单独显示它们
我有两个xib文件,一个显示登录视图,另一个显示登录成功后要执行的步骤.我很难让它发挥作用.我创建了macos项目而不是ios并使用safariservices,因此它也适用于safari扩展.
这就是我所做的 import SafariServices class SafariExtensionViewController: SFSafariExtensionViewController { @IBOutlet weak var passwordMessage: NSTextField! @IBOutlet weak var emailMessage: NSTextField! @IBOutlet weak var message: NSTextField! @IBOutlet weak var email: NSTextField! @IBOutlet weak var password: NSSecureTextField! static let shared = SafariExtensionViewController() override func viewDidLoad() { self.preferredContentSize = NSSize(width: 300,height: 250) message.stringValue = "" emailMessage.stringValue = "" passwordMessage.stringValue = "" } override func viewDidAppear() { if let storedEmail = UserDefaults.standard.object(forKey: "email") as? String { if let stepView = Bundle.mainBundle.loadNibNamed(NSNib.Name(rawValue: "ExtensionStepsViewController"),owner: nil,topLevelObjects: nil)[0] { self.view.addSubview(stepView) } } } @IBAction func userLogin(_ sender: Any) { let providedEmailAddress = email.stringValue let providedPassword = password.stringValue let isEmailAddressValid = isValidEmailAddress(emailAddressString: providedEmailAddress) self.message.stringValue = "" emailMessage.stringValue = "" passwordMessage.stringValue = "" if isEmailAddressValid && providedPassword.count > 0 { /* login process is handled here and store the email in local storage /* /* TODO for now email is not stored in browser localstorage which has to be fixed */ let controller = "ExtensionStepsViewController" let subview = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: controller),bundle: nil) self.view.addSubview(subview.view) } } } 这样我得到的错误就像Type Bool没有下标成员我的文件结构看起来像这样.
我正在使用xcode 10,swift 4,一切都是新的. UPDATE 我在viewDidAppear中使用了以下块(如果localstorage中有电子邮件,然后显示扩展步骤视图而不是登录屏幕)和登录成功时内部登录功能,但它没有导航到该ExtensionStepsView let controller = "ExtensionStepsViewController" let subview = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: controller),bundle: nil) self.view.addSubview(subview.view) 用例是在初始时显示登录,但如果用户登录则显示另一个视图,但问题是现在视图已合并 解决方法
你得到错误“类型Bool没有下标成员”,因为
Bundle的
loadNibNamed(_:owner:topLevelObjects:)方法返回没有
subscript成员的
Bool结构所以你不能写
true[0] 如何正确使用此方法请参见link和示例: var topLevelObjects : NSArray? if Bundle.main.loadNibNamed(NSNib.Name(rawValue: "ExtensionStepsViewController"),owner: self,topLevelObjects: &topLevelObjects) { let topLevelObjects!.first(where: { $0 is NSView }) as? NSView } 视图已合并,因为您没有从superview中删除先前的视图,并将ExtensionStepsViewController中的视图添加到同一个superview. 您可以执行以下步骤来完成您的问题: >使SafariExtensionViewController继承自SFSafariExtensionViewController,它将是两个子视图控制器(如LoginViewController和ExtensionStepsViewController)的容器(和父),并将用于在它们之间导航. 作为示例,但是您必须使用您的实现SafariExtensionViewController而不是ParentViewController,如上所述. public protocol LoginViewControllerDelegate: class { func loginViewControllerDidLoginSuccessful(_ loginVC: LoginViewController) } public class LoginViewController: NSViewController { weak var delegate: LoginViewControllerDelegate? @IBAction func login(_ sender: Any) { // login logic let isLoginSuccessful = true if isLoginSuccessful { self.delegate?.loginViewControllerDidLoginSuccessful(self) } } } public class ExtensionStepsViewController: NSViewController { } public class ParentViewController: NSViewController,LoginViewControllerDelegate { weak var login: LoginViewController! // using of force unwrap is anti-pattern. consider other solutions weak var steps: ExtensionStepsViewController! public override func viewDidLoad() { let login = LoginViewController(nibName: NSNib.Name(rawValue: "LoginViewController"),bundle: nil) login.delegate = self // change login view frame if needed login.view.frame = self.view.frame self.view.addSubview(login.view) // instead of setting login view frame you can add appropriate layout constraints self.addChildViewController(login) self.login = login let steps = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: "ExtensionStepsViewController"),bundle: nil) steps.view.frame = self.view.frame self.addChildViewController(steps) self.steps = steps } // MARK: - LoginViewControllerDelegate public func loginViewControllerDidLoginSuccessful(_ loginVC: LoginViewController) { self.transition(from: self.login,to: self.steps,options: .slideLeft) { // completion handler logic print("transition is done successfully") } } } Here是这个例子的快捷游乐场. UPD: 您可以通过以下几种方式实例化NSViewController: >使用允许从.storyboard文件加载NSViewController视图的NSStoryboard: let storyboard = NSStoryboard(name: NSStoryboard.Name("NameOfStoryboard"),bundle: nil) let viewController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("NSViewControllerIdentifierInStoryboard")) >使用NSViewController的相应initialiser从.xib文件加载它的视图: let steps = ExtensionStepsViewController(nibName: NSNib.Name(rawValue: "ExtensionStepsViewController"),bundle: nil) >使用默认初始化程序,但如果xib文件的名称与视图控制器类的名称不同,则必须通过重写loadView()方法直接加载视图: let steps = ExtensionStepsViewController() // Also you have to override loadView() method of ExtensionStepsViewController. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |