简体   繁体   English

如何在同一ViewController中初始化两个NSObject实例-Swift

[英]How Do I Initialize Two Instances of NSObject in the same ViewController - Swift

Please bear with me. 请多多包涵。 I'm new to programming and new to StackOverflow. 我是编程新手,还是StackOverflow的新手。 I hope that my question will grant me a warm response for entering the programming community. 我希望我的问题能使我对进入编程社区产生热情的响应。 An acquaintance, whose opinion I trust, told me to post this email to him on StackOverflow. 我信任他的一个熟人,让我将此邮件发送到StackOverflow上给他。

What do I have to do to get two instances of NSObject to work in the same ViewController? 如何使两个NSObject实例在同一ViewController中工作? I've initialized an NSObject subclass called SideBar and RightSideBar. 我已经初始化了一个名为SideBar和RightSideBar的NSObject子类。 They both draw from NSObject. 它们都从NSObject绘制。 The cells in the menu are called created by a TableViewController I created programatically. 菜单中的单元格由我以编程方式创建的TableViewController创建。 I followed a tutorial that did everything programmatically because I didn't know that Storyboard is better for building things. 我遵循了一个以编程方式完成所有操作的教程,因为我不知道Storyboard可以更好地构建东西。

Below is the code base. 下面是代码库。

EDITED: Sorry for being long winded. 编辑:很抱歉长期困扰。 I don't know how to make this any shorter and as complete 我不知道如何使它简短而完整

=========== ===========

****Note the SideBar subclass is the left menu. ****请注意,SideBar子类是左侧菜单。 The RightSideBar class has the same initializer setup and is the right menu. RightSideBar类具有相同的初始化程序设置,并且是右侧菜单。 I want to be able to make them both appear on the same ViewController in the same instance of the same ViewController if possible.**** 我希望能够尽可能使它们都出现在同一ViewController的同一实例中的同一ViewController上。

This is the left TableViewController: 这是左侧的TableViewController:

import UIKit
//this protocol of the sidebar delegate manages the selection of the item in the row.
protocol SidebarTableViewControllerDelegate {

     func sidebarControlDidSelectRow(indexPath: NSIndexPath)

}

class SidebarTableViewController: UITableViewController {

    //setting up the delegate and array of menu items.
    var delegate:SidebarTableViewControllerDelegate?
    var tableData:Array <String> = []
    var imageData:[UIImage] = []


    // MARK: - Table view data source

    //Setting up the number of sections in the menu
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 1
    }
    //Setting up the number of items in the menu
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return tableData.count
    }

    //Setting up the menu look for the main screen after login.
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell

        if cell == nil {

            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
            //configure the cell...

            cell!.backgroundColor = UIColor.clearColor()
            cell!.textLabel?.textColor = UIColor.darkTextColor()

            let selectedView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
            selectedView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.3)

            cell!.selectedBackgroundView = selectedView

        }

            cell!.textLabel!.text = tableData[indexPath.row]
            cell!.imageView!.image = imageData[indexPath.row]


            return cell!

    }

    //Setting up the height for each cell of the table
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        return 45.0

    }

    //Setting up the selection of the item in the cell.
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        delegate?.sidebarControlDidSelectRow(indexPath)
    }

    override func viewDidLoad() {

    }

    override func didReceiveMemoryWarning() {

    }

}

This is the right table view controller: 这是正确的表视图控制器:

//setting up the RightSidebarControllerDelegate
protocol RightSidebarTableViewControllerDelegate {

    func rightSidebarControlDidSelectRow(indexPath: NSIndexPath)

}

class RightSidebarTableViewController: UITableViewController {

    //setting up the delegate and array of menu items.
    var delegate:RightSidebarTableViewControllerDelegate?
    var rightTableData:Array <String> = []
    var rightImageData:[UIImage] = []


    // MARK: - Table view data source

    //Setting up the number of sections in the menu
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 1
    }
    //Setting up the number of items in the menu
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return rightTableData.count
    }

    //Setting up the menu look for the main screen after login.
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell

        if cell == nil {

            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
            //configure the cell...

            cell!.backgroundColor = UIColor.clearColor()
            cell!.textLabel?.textColor = UIColor.darkTextColor()

            let selectedView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
            selectedView.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.3)

            cell!.selectedBackgroundView = selectedView

        }

        cell!.textLabel!.text = rightTableData[indexPath.row]
        cell!.imageView!.image = rightImageData[indexPath.row]


        return cell!

    }

    //Setting up the height for each cell of the table
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        return 45.0

    }

    //Setting up the selection of the item in the cell.
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        delegate?.rightSidebarControlDidSelectRow(indexPath)
    }

    override func viewDidLoad() {

    }

    override func didReceiveMemoryWarning() {

    }

}

Here is where my problems may start with SideBar:NSObject. 这是我的问题可能始于SideBar:NSObject的地方。 This is the left SideBar to be initialized: 这是要初始化的左侧边栏:

import UIKit

@objc protocol SideBarDelegate {

    func sideBarDidSelectButtonAtIndex (index: Int)
    optional func sideBarWillClose()
    optional func sideBarWillOpen()
    optional func sideBarWillDeinitialize()

}

//this class sets up the actual sidebar.
class SideBar: NSObject, SidebarTableViewControllerDelegate {

    //width of the bar, tableview setup, and views for the sidebar
    let barWidth:CGFloat = 175.0
    let sideBarTableViewTopInset:CGFloat = 25.0
    let sideBarContainerView:UIView = UIView()
    let sideBarTableViewController:SidebarTableViewController = SidebarTableViewController()
    var originView:UIView!

    //var for dynamic effect and controlling the sidebar
    var animator:UIDynamicAnimator!
    var delegate:SideBarDelegate?
    var isSideBarOpen:Bool = false


    //initializer for the "SideBar" class.
    override init() {
        super.init()

    }

    //initializer for the tableView of menu items.
    init(sourceView: UIView, menuItems: Array<String>, menuImages: [UIImage]){
        super.init()

        //initializing the views and animation for the menu.
        originView = sourceView
        sideBarTableViewController.tableData = menuItems
        sideBarTableViewController.imageData = menuImages
        setupSideBar()
        animator = UIDynamicAnimator(referenceView: originView)

    }

    //function for setting up the sidebar.
    func setupSideBar () {

        //setting up the frame/outline of the side bar.
        sideBarContainerView.frame = CGRectMake(-barWidth, originView.frame.origin.y + 45, barWidth, originView.frame.size.height)

        //setting up the color of the sidebar.
        sideBarContainerView.backgroundColor = UIColor.clearColor()

        //disables subviews from being confined to the sidebar.
        sideBarContainerView.clipsToBounds = false

        //placing the sidebar in the UIView
        originView.addSubview(sideBarContainerView)

        //adding blur to the menu.
        let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
        blurView.frame = sideBarContainerView.bounds
        sideBarContainerView.addSubview(blurView)


        //setting up controls for the sidebar
        sideBarTableViewController.delegate = self
        sideBarTableViewController.tableView.frame = sideBarContainerView.bounds
        sideBarTableViewController.tableView.clipsToBounds = false

        //disabling the scroll feature. Delete to keep the scroll feature.
        sideBarTableViewController.tableView.scrollsToTop = false

        //This will remove separators in the UITableCell. Delete to keep separators.
        sideBarTableViewController.tableView.separatorStyle = UITableViewCellSeparatorStyle.None

        //This sets the background color of the sidebar and creates the inset.
        sideBarTableViewController.tableView.backgroundColor = UIColor.clearColor()
        sideBarTableViewController.tableView.contentInset = UIEdgeInsets(top: sideBarTableViewTopInset, left: 0, bottom: 0, right: 0)

        //reloads the sidebar and adds the container view to the sideBarTableViewController.
        sideBarTableViewController.tableView.reloadData()
        sideBarContainerView.addSubview(sideBarTableViewController.tableView)
    }

    func showSideBar(shouldOpen: Bool){
        animator.removeAllBehaviors()
        isSideBarOpen = shouldOpen

        //simple if and else statements to define the direction of animation and intensity of animation
        let gravityX:CGFloat = (shouldOpen) ? 0.5 : -0.5
        let magnitude:CGFloat = (shouldOpen) ? 20 : -20
        let boundaryX:CGFloat = (shouldOpen) ? barWidth : -barWidth

        //controls the behavior of the animation.
        let gravityBehavior: UIGravityBehavior = UIGravityBehavior(items: [sideBarContainerView])
        gravityBehavior.gravityDirection = CGVectorMake(gravityX, 0)
        animator.addBehavior(gravityBehavior)

        let collisionBehavior: UICollisionBehavior = UICollisionBehavior(items: [sideBarContainerView])
        collisionBehavior.addBoundaryWithIdentifier("sideBarBoundary", fromPoint: CGPointMake(boundaryX, 20), toPoint: CGPointMake(boundaryX, originView.frame.size.height))
        animator.addBehavior(collisionBehavior)

        let pushBehavior:UIPushBehavior = UIPushBehavior(items: [sideBarContainerView], mode: UIPushBehaviorMode.Instantaneous)
        pushBehavior.magnitude = magnitude
        animator.addBehavior(pushBehavior)

        let sideBarBehavior:UIDynamicItemBehavior = UIDynamicItemBehavior(items: [sideBarContainerView])
        sideBarBehavior.elasticity = 0.3
        animator.addBehavior(sideBarBehavior)
    }
    func sidebarControlDidSelectRow(indexPath: NSIndexPath) {
        delegate?.sideBarDidSelectButtonAtIndex(indexPath.row)
    }

}

This is the right SideBar:NSObject that will eventually initialize the right menu. 这是右边的SideBar:NSObject,它将最终初始化右边的菜单。

import UIKit
@objc protocol RightSideBarDelegate {

    func rightSideBarDidSelectButtonAtIndex (index: Int)
    optional func sideBarWillClose()
    optional func sideBarWillOpen()

}

class RightSideBar: NSObject, RightSidebarTableViewControllerDelegate {

    //width of the bar, tableview setup, and views for the sidebar
    let barWidth:CGFloat = 175.0
    let rightSideBarTableViewTopInset:CGFloat = 25.0
    let rightSideBarContainerView:UIView = UIView()
    let rightSideBarTableViewController:RightSidebarTableViewController = RightSidebarTableViewController()
    var rightOriginView:UIView!

    //var for dynamic effect and controlling the sidebar
    var animator:UIDynamicAnimator!
    var delegate:RightSideBarDelegate?
    var isSideBarOpen:Bool = false


    //initializer for the "SideBar" class.
    override init() {
        super.init()

    }

    //initializer for the tableView of menu items.
    init(rightSourceView: UIView, rightMenuItems: Array<String>, rightMenuImages: [UIImage]){
        super.init()

        //initializing the views and animation for the menu.
        rightOriginView = rightSourceView
        rightSideBarTableViewController.rightTableData = rightMenuItems
        rightSideBarTableViewController.rightImageData = rightMenuImages
        setupSideBar()
        animator = UIDynamicAnimator(referenceView: rightOriginView)

    }

    //function for setting up the sidebar.
    func setupSideBar () {

        //setting up the frame/outline of the side bar.
        rightSideBarContainerView.frame = CGRectMake(rightOriginView.frame.size.width + barWidth , rightOriginView.frame.origin.y + 45, barWidth, rightOriginView.frame.size.height)

        //setting up the color of the sidebar.
        rightSideBarContainerView.backgroundColor = UIColor.clearColor()

        //disables subviews from being confined to the sidebar.
        rightSideBarContainerView.clipsToBounds = false

        //placing the sidebar in the UIView
        rightOriginView.addSubview(rightSideBarContainerView)

        //adding blur to the menu.
        let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
        blurView.frame = rightSideBarContainerView.bounds
        rightSideBarContainerView.addSubview(blurView)


        //setting up controls for the sidebar
        rightSideBarTableViewController.delegate = self
        rightSideBarTableViewController.tableView.frame = rightSideBarContainerView.bounds
        rightSideBarTableViewController.tableView.clipsToBounds = false

        //disabling the scroll feature. Delete to keep the scroll feature.
        rightSideBarTableViewController.tableView.scrollsToTop = false

        //This will remove separators in the UITableCell. Delete to keep separators.
        rightSideBarTableViewController.tableView.separatorStyle = UITableViewCellSeparatorStyle.None

        //This sets the background color of the sidebar and creates the inset.
        rightSideBarTableViewController.tableView.backgroundColor = UIColor.clearColor()
        rightSideBarTableViewController.tableView.contentInset = UIEdgeInsets(top: rightSideBarTableViewTopInset, left: 0, bottom: 0, right: 0)

        //reloads the sidebar and adds the container view to the rightSideBarTableViewController.
        rightSideBarTableViewController.tableView.reloadData()
        rightSideBarContainerView.addSubview(rightSideBarTableViewController.tableView)

    }

    func showSideBar(shouldOpen: Bool){
        animator.removeAllBehaviors()
        isSideBarOpen = shouldOpen

        //simple if and else statements to define the direction of animation and intensity of animation
        let gravityX:CGFloat = (shouldOpen) ? -0.5 : 0.5
        let magnitude:CGFloat = (shouldOpen) ? -20 : 20
        let boundaryX:CGFloat = (shouldOpen) ? -barWidth : barWidth

        //controls the behavior of the animation.
        let gravityBehavior: UIGravityBehavior = UIGravityBehavior(items: [rightSideBarContainerView])
        gravityBehavior.gravityDirection = CGVectorMake(gravityX, 0)
        animator.addBehavior(gravityBehavior)

        let collisionBehavior: UICollisionBehavior = UICollisionBehavior(items: [rightSideBarContainerView])
        collisionBehavior.addBoundaryWithIdentifier("sideBarBoundary", fromPoint: CGPointMake(boundaryX, 20), toPoint: CGPointMake(boundaryX, rightOriginView.frame.size.height))
        animator.addBehavior(collisionBehavior)

        let pushBehavior:UIPushBehavior = UIPushBehavior(items: [rightSideBarContainerView], mode: UIPushBehaviorMode.Instantaneous)
        pushBehavior.magnitude = magnitude
        animator.addBehavior(pushBehavior)

        let sideBarBehavior:UIDynamicItemBehavior = UIDynamicItemBehavior(items: [rightSideBarContainerView])
        sideBarBehavior.elasticity = 0.3
        animator.addBehavior(sideBarBehavior)


    }
    func rightSidebarControlDidSelectRow(indexPath: NSIndexPath) {
        delegate?.rightSideBarDidSelectButtonAtIndex(indexPath.row)
    }

}

Finally this is my current code for the DoubleMenuViewController. 最后,这是我当前的DoubleMenuViewController代码。 Something happens when I segue to the DoubleMenuViewController to break the menus. 当我选择使用DoubleMenuViewController中断菜单时,会发生某些事情。 The menus won't even load. 菜单甚至都不会加载。 However, if I'm in a SingleMenuViewController that only calls SideBar:NSObject then the code will work so long as I'm only calling one menu. 但是,如果我在仅调用SideBar:NSObject的SingleMenuViewController中,则只要我仅调用一个菜单,代码就可以工作。 In this DoubleMenuViewController, I have the initialization section commented out for the RightSideBar class because I'm working on a solution. 在此DoubleMenuViewController中,我正在为RightSideBar类注释掉初始化部分,因为我正在研究解决方案。 I know this code for this ViewController is garbled. 我知道此ViewController的这段代码是乱码。 I'm trying everything I can think of. 我正在尝试我能想到的一切。 See my remarks after the code to see what I've tried: 在代码后查看我的评论,以查看尝试过的内容:

import UIKit

class DoubleMenuViewController: UIViewController, SideBarDelegate,       RightSideBarDelegate {

    var sideBar:SideBar?
    var ondemandSideBar:SideBar {

        get {

            if sideBar == nil {

            //setting up the menu items for the sidebar.
            sideBar = SideBar(sourceView: self.view, menuItems: ["Home", "Share", "About", "Help"], menuImages: [homeImage!, shareImage!, aboutImage!, helpImage!])
            sideBar!.delegate = self
            SideBar.new()

            }

            return sideBar!
        }
    }

    //initializes the "RightSideBar"
    var rightSideBar:RightSideBar?
    var ondemandRightSideBar:RightSideBar {

        get {

            if rightSideBar == nil {

            rightSideBar = RightSideBar(rightSourceView: self.view, rightMenuItems: [//Other items], rightMenuImages: [//Other Items])
            rightSideBar!.delegate = self
            RightSideBar.new()

            }

            return rightSideBar!
        }
    }


    var homeImage = UIImage(named: "Home")
    var shareImage = UIImage(named: "Share")
    var aboutImage = UIImage(named: "About")
    var helpImage = UIImage(named: "Help")

    @IBOutlet weak var currentMenuControl: UIBarButtonItem!

    @IBAction func currentMenuDisplay(sender: AnyObject) {

        if currentMenuControl.tag == 1 {

            ondemandSideBar.showSideBar(true)
            currentMenuControl.tag = 0

        } else {

            ondemandSideBar.showSideBar(false)
            currentMenuControl.tag = 1

        }

    }

    @IBOutlet weak var progressionMenuControl: UIBarButtonItem!

    @IBAction func progressionMenuDisplay(sender: AnyObject) {

        if progressionMenuControl.tag == 1 {

            ondemandRightSideBar.showSideBar(true)
            progressionMenuControl.tag = 0

        } else {

            ondemandRightSideBar.showSideBar(false)
            progressionMenuControl.tag = 1
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func sideBarDidSelectButtonAtIndex(index: Int) {

        switch index {

         //segues
        }
    }

    func rightSideBarDidSelectButtonAtIndex(index: Int) {

        switch index {

         //segues
        }
    }

}

Here's what I've tried: 这是我尝试过的:

  1. I've tried altering the positioning of CGFloats since SubViews seem to come from the left. 由于SubViews似乎来自左侧,因此我尝试过更改CGFloat的位置。

  2. I've renamed all the RightSideBar variables and class names everything to overcome a runtime confusion in instance variables and class names. 我已将所有RightSideBar变量和类名都重命名,以克服实例变量和类名在运行时的混乱。 This includes renaming the initializers that you saw in the NSObject SubClass and the target view controller. 这包括重命名您在NSObject SubClass和目标视图控制器中看到的初始化程序。

  3. I've tried using control flow in the viewDidLoad method with a button tag. 我尝试在带有按钮标签的viewDidLoad方法中使用控制流。 I took away the swipe features to show the menu and added buttons because I thought system was struggling to deal with the Swipes. 我取消了滑动功能以显示菜单并添加了按钮,因为我认为系统正在努力应对滑动。

  4. I've tried deinitializing in the SideBar subclass file of NSObject. 我尝试在NSObject的SideBar子类文件中取消初始化。 All that got me was an infinite loop that crashed the application after login. 使我感到困惑的是无限循环,登录后崩溃了该应用程序。

  5. Then I tried ondemand initialization in the targetViewController.....DoubleMenuViewController and SingleMenuViewController. 然后我尝试在targetViewController中按需进行初始化..... DoubleMenuViewController和SingleMenuViewController。 I returned to a working menu with buttons in the SingleMenuViewController but it still won't show the left and right menu in the DoubleMenuViewController. 我返回了带有SingleMenuViewController中的按钮的工作菜单,但是在DoubleMenuViewController中它仍然不会显示左右菜单。

  6. Last I tried deinitializing the SideBar (left SideBar) and the RightSideBar in the DoubleMenuViewController. 最后,我尝试在DoubleMenuViewController中取消初始化SideBar(左侧SideBar)和RightSideBar。 However, when I add println() functions to all my sections the debugger doesn't run the print function for me to get values of objects or even show typed states like "This" . 但是,当我将println()函数添加到我的所有部分时,调试器不会为我运行print函数来获取对象的值,甚至不会显示诸如“ This”之类的类型化状态。 I added the print functions because I wasn't sure if I would know when deinitialization and reinitialization occurred. 我添加了打印功能,因为我不确定是否知道何时进行初始化和重新初始化。

It seems that my menu is initialized from the SideBar: NSObject file and the RightSideBar:NSObject file. 看来我的菜单是从SideBar:NSObject文件和RightSideBar:NSObject文件初始化的。 What I mean is that my menu is being created before I hit the target view controller. 我的意思是,在我击中目标视图控制器之前就已经创建了菜单。 This isn't a problem for me so long as I can get the compiler to initialize the SideBar and the RightSideBar in the same View Controller, but it won't do that. 只要我可以让编译器在同一个View Controller中初始化SideBar和RightSideBar,这对我来说就不是问题,但是它不会那样做。

I just need to be able to control both menus with swipes or button taps. 我只需要能够通过滑动或点击按钮来控制两个菜单。

I think I have a problem with my initializers overriding each other. 我认为我的初始化程序相互覆盖时遇到问题。

However, I don't know how to fix that problem. 但是,我不知道如何解决该问题。 I've read through the Swift manual and read articles on the internet. 我已经阅读了Swift手册并在互联网上阅读了文章。 I've also searched StackOverflow. 我还搜索了StackOverflow。

You ask: 你问:

How do I Initialize two instances of NSObject in the same view controller? 如何在同一视图控制器中初始化两个NSObject实例?

Setting aside why you're dealing with NSObject at all (in Objective-C all classes have to subclass from NSObject ultimately, in Swift that's no longer the case), if you want to instantiate two objects, you simply have to have one property for each. 抛开为什么要使用NSObject原因(在Objective-C中,所有类最终都必须从NSObject子类,而在Swift中则不再如此),如果要实例化两个对象,则只需要具有一个属性即可每。

If these are lazily instantiated, as your code snippet suggests, then you have to identify where that lazily instantiated property is referenced (eg you might trigger it from a "swipe from edge" gesture) or what have you. 如果这些是延迟实例化的,如您的代码片段所建议,那么您必须确定引用该延迟实例化的属性的位置(例如,您可以通过“从边缘滑动”手势来触发它)或所拥有的东西。 Set a breakpoint in the code that references that lazily instantiated property and make sure you're getting there at all. 在引用延迟实例化属性的代码中设置一个断点,并确保您完全到达那里。

-- -

I had some observations on one of your code snippets. 我对您的其中一个代码段有一些观察。 You say that you're instantiating your side bar like so: 您说要像这样实例化侧边栏:

var sideBar : SideBar?
var ondemandSideBar : SideBar {
    get {
        if sideBar == nil {
            sideBar = SideBar(sourceView, menuItems, menuImage etc.)
            sideBar!.delegate
            SideBar.new()
        }
    }
}

I don't think that's what you're really doing because you're not setting the delegate, you're both instantiating the SideBar as well as calling new (which you shouldn't be doing from Swift), you're not returning a value, etc. 我不认为这是您真正在做的事情,因为您没有设置委托,您既在实例化SideBar以及在调用new (您不应从Swift进行此操作),也没有返回值等

Also, that pattern of having a stored property that is instantiated by some computed property has a certain Objective-C je ne sais quoi. 同样,具有由某些计算出的属性实例化的存储属性的模式具有一定的Objective-C je sais quoi。 I'm inferring that you want a lazily instantiated property. 我推断您想要一个延迟实例化的属性。 If that's the case, I'd be inclined to use a single lazy stored property. 如果是这种情况,我倾向于使用一个lazy存储属性。 And I'd then set that property lazily using a closure: 然后,我会使用闭包延迟设置该属性:

I'd expect something like this pattern 我希望这样的事情

protocol SideBarDelegate : class {                         // specify class so we can use `weak` reference
    func didChooseMenuItem(sender: SideBar, item: Int)
}

class SideBar {
    weak var delegate: SideBarDelegate?                    // make sure this is weak to avoid strong reference cycle
}

class ViewController: UIViewController, SideBarDelegate {

    lazy var sideBar: SideBar = {
        let _sideBar = SideBar(sourceView, menuItems, menuImage, etc.)
        _sideBar.delegate = self
        return _sideBar
    }()

    func didChooseMenuItem(sender: SideBar, item: Int) {
        // handle it here
    }

    // etc.
}

This way, the sideBar won't be instantiated until you reference sideBar somewhere in your code, but when you do, it will be instantiated with the code inside that closure. 这样,直到您在代码中的某处引用sideBarsideBar才会被实例化,但是当您这样做时, sideBar将会在该闭包中的代码实例化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在NSObject类中快速引用viewcontroller? - How to take reference of viewcontroller in NSObject class in swift? 如何在NSObject类中添加动态行为:Swift - How do i add dynamic behaviour in NSObject class : Swift 如何在Swift中检查字典中的NSObject项目? - How do I check a NSObject item in a dictionary in Swift? 如何使用iOS的NSCoder,NSObject和Swift 3解码Double - How do I decode a Double using NSCoder, NSObject and Swift 3 for iOS 如何在ViewController中初始化实例变量和属性 - How do I initialize instance variables and properties in the ViewController 如果没有Storyboard,如何初始化自定义ViewController? - How do I initialize a custom ViewController when there's no Storyboard? 在 swift 中,当不同的按钮通向同一个 ViewController 时,我如何知道按下了哪个按钮? - How do I know in swift which button was pressed when different buttons lead to the same ViewController? 如何快速初始化一个空的NSMutableAttributedString? - How do I initialize an empty NSMutableAttributedString in swift? 两个viewController swift iOS中的uiwebview的相同实例 - same instance of uiwebview in two viewController swift ios 我如何在 swift 3 的一个视图控制器中填充两个不同的表视图 - How i can fill two different tableview in one viewcontroller in swift 3
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM