iOS使用xib +全局方法进行叠加UIView(Swift)

时间:2015-01-22 17:43:50

标签: ios swift global xib

我正在编写一个应用程序,应该在特定情况下显示叠加层,例如缺少为应用启用的位置服务。

Overlay是一个带有UIImageView(背景)的UIView,一个UILabel(标题)和一个调用特定动作的UIButton。我想使用Interface Builder来设置覆盖UI,但我想回忆覆盖并在不同的UIViewControllers上显示它,具体取决于何时检测到缺少位置服务。

我已经设置了一个自定义类(UIView的子类)来链接xib文件。代码如下:

class LaunchCustomScreen: UIView
{

   @IBOutlet var title: UILabel!
   @IBOutlet var enableLocationButton: UIButton!
   @IBOutlet var waitingIndicator: UIActivityIndicatorView!
   @IBOutlet var bckgroundImage: UIImageView!

   func setupDefault()
   {
       title.text = "Location Services Required"
       enableLocationButton.setTitle("Enable Location Services", forState: UIControlState.Normal)
       enableLocationButton.addTarget(self,
        action: "promptUserForLocation",
        forControlEvents: UIControlEvents.TouchUpInside)

       hideLocButton()
   }

   func hideLocButton()
   {
       enableLocationButton.hidden = true
   }

   func showLocButton()
   {
       enableLocationButton.hidden = false
   }
}

然后我创建了类LaunchCustomScreen的xib文件,并将IBOutlets链接到其中的所有对象(UILabels,UIBUtton,UIImageView)

然后我设置了一些要从任何其他UIViewController调用的全局函数,以显示/隐藏特定视图控制器上的叠加层,并使用隐藏或可见的UIButton进行配置(当用户位置时,它将被隐藏,并带有等待指示符还在加载)。以下相关代码:

func setupLaunchDefault(vc: UIViewController) -> LaunchCustomScreen
{
    for aSubview in vc.view.subviews
    {
        if aSubview.isKindOfClass(LaunchCustomScreen)
        {
            NSLog("Found already a launch screen. Removing")
            aSubview.removeFromSuperview()
        }
    }

    var screen: LaunchCustomScreen = LaunchCustomScreen()
    screen.setupDefault()
    return screen
}

func showLaunchAskLocation(vc:UIViewController)
{
    var screen = setupLaunchDefault(vc)
    screen.bounds = vc.view.bounds
    screen.showLocButton()
    vc.view.addSubview(screen)
} 

现在我正在尝试解决方案是否有效并且在setupLaunchDefault函数上崩溃了。原因是即使创建了LaunchCustomSCreen的实例,变量(title,enableLocationButton)仍然是零。我觉得它们应该是非零的,这要归功于xOutlet到xib ...我错过了什么?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

  

我已经设置了一个自定义类(UIView的子类)来链接xib文件

不,你没有。没有这样的"链接"是可能的。

  

我错过了什么?

你不会错过任何东西,因为你已经弄清楚了!

仅仅凭空创建一个LaunchCustomScreen实例(即通过说LaunchCustomScreen(),就像你正在做的那样)只创建一个这个类的实例。 .xib (nib)文件 。没有魔法"链接"班级和笔尖之间的任何东西!因此,没有任何事情会导致这些属性获得任何价值。正如您正确解释的那样,nil

您已在nib 中设计并配置了 LaunchCustomScreen 的一个特殊特定实例那个是其出口连接的实例,在同一个笔尖中。因此,如果你想要一个带有连接插座的LaunchCustomScreen实例,你必须加载笔尖!加载nib完全等同于在nib中创建一个实例 - 它一种实例化形式。在这里,它是你想要的实例化形式,因为这个实例就是你想要的实例。

所以,答案是:LaunchCustomScreen()来获取LaunchCustomScreen实例(screen)。相反,加载nib 以获取LaunchCustomScreen实例 - 一切都会好的。

因此,我们假设您的 .xib 文件名为 LaunchCustomScreen.xib 。你会说:

let arr = NSBundle.mainBundle().loadNibNamed("LaunchCustomScreen", owner: nil, options: nil)
let screen = arr[0] as UIView

第一个结果arr是从nib实例化的顶级对象数组。这些对象中的第一个(可能是数组中唯一的成员)是您追求的视图!所以你把它投射到UIView,你就可以把它粘在你的界面上了。由于视图来自笔尖,因此设置了它的出口,这就是你所追求的。您可以根据需要多次执行此操作,以获得尽可能多的副本"你喜欢这种观点。