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

叠加层是一个UIView,具有一个UIImageView(背景),一个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的实例,变量(标题,enableLocationButton)仍然为零。尽管由于ibOut的IBOutlet,我还是应该让他们成为零!我想念的是什么?

预先感谢您的帮助!

最佳答案

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

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

我想念什么?

您不会丢失任何东西,因为您已经知道了!

仅仅凭空创建一个LaunchCustomScreen实例(即,如您所说的LaunchCustomScreen())仅创建此类的实例。它与.xib(nib)文件无关!在 class 和笔尖之间,没有魔术的“联系”!因此,不会发生任何导致这些属性获得任何值的事情。正如您正确解释的那样,它们是nil

您已经在笔尖中设计并配置了LaunchCustomScreen的一个特殊实例。那是在同一笔尖内连接插座的实例。因此,如果要使用带有连接插座的LaunchCustomScreen实例,则必须加载笔尖!加载笔尖与创建笔尖中的内容完全等效-这是实例化的一种形式。在这里,它就是您想要的实例化形式,因为此实例就是您想要的实例。

因此,答案是:不要说LaunchCustomScreen()来获取LaunchCustomScreen实例(screen)。相反,加载笔尖以获取LaunchCustomScreen实例-一切都会好起来。

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

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

第一个结果arr是从笔尖实例化的顶级对象的数组。这些对象中的第一个(可能是数组的唯一成员)是您想要的视图!因此,将其转换为UIView并准备将其粘贴到界面中。由于视图来自笔尖,因此设置了出口,这正是您所追求的。您可以根据需要多次执行此操作,以根据需要获取尽可能多的该视图“副本”。

关于ios - iOS使用xib +全局方法覆盖UIView(Swift),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28095307/

10-09 18:06