iOS 使用 xib + 全局方法覆盖 UIView (Swift)
iOS using xib + global methods for overlay UIView (Swift)
我正在编写一个应在特定情况下显示叠加层的应用程序,例如该应用程序未启用定位服务。
Overlay 是一个 UIView,带有一个 UIImageView(背景)、一个 UILabel(标题)和一个调用特定操作的 UIButton。我想使用 Interface Builder 来设置叠加层 UI 但我想调用叠加层并将其显示在不同的 UIViewControllers 上,具体取决于何时缺少位置服务检测到。
我已经为 link 一个 xib 文件设置了自定义 class(UIView 的子class)。代码如下:
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
}
}
然后我创建了 Class LaunchCustomScreen 的 xib 文件,我 link 将 IBOutlets 编辑到其中的所有 objects (UI 标签,UIBUtton, UIImageView)
然后我设置了一些全局函数,以便从任何其他 UIViewController 调用,以便 show/hide 在特定视图控制器上覆盖并使用 [=34 配置它=] 按钮隐藏或可见(当用户位置仍在加载时,它将被隐藏并带有等待指示器)。相关代码如下:
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) 仍然是 nil。我虽然他们应该 non-nil 感谢 xib 的 IBOutlet...我错过了什么?
提前感谢您的帮助!
I have set up a custom class (subclass of UIView) to link a xib file
不,你没有。没有这样的 "link" 是可能的。
what am I missing?
你没有遗漏任何东西,因为你已经想通了!
只是凭空创建一个 LaunchCustomScreen 实例(即像您一样说 LaunchCustomScreen()
)只是创建此 class 的一个实例。它与 .xib (nib) 文件没有任何关系! class 和笔尖之间没有任何魔法 "link"!因此,没有任何事情会导致这些属性获得任何值。正如您正确解释的那样,它们是 nil
.
您已经在 nib 中设计并配置了 LaunchCustomScreen 的一个特殊实例。 那个是插座连接的实例,在同一个笔尖。因此,如果您想要一个带有连接插座的 LaunchCustomScreen 实例,您必须 加载 nib!加载 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 并准备好将其粘贴到您的界面中。由于视图来自笔尖,因此设置了它的出口,这就是您所追求的。您可以根据需要多次执行此操作,以获得任意多的此视图 "copies"。
我正在编写一个应在特定情况下显示叠加层的应用程序,例如该应用程序未启用定位服务。
Overlay 是一个 UIView,带有一个 UIImageView(背景)、一个 UILabel(标题)和一个调用特定操作的 UIButton。我想使用 Interface Builder 来设置叠加层 UI 但我想调用叠加层并将其显示在不同的 UIViewControllers 上,具体取决于何时缺少位置服务检测到。
我已经为 link 一个 xib 文件设置了自定义 class(UIView 的子class)。代码如下:
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
}
}
然后我创建了 Class LaunchCustomScreen 的 xib 文件,我 link 将 IBOutlets 编辑到其中的所有 objects (UI 标签,UIBUtton, UIImageView)
然后我设置了一些全局函数,以便从任何其他 UIViewController 调用,以便 show/hide 在特定视图控制器上覆盖并使用 [=34 配置它=] 按钮隐藏或可见(当用户位置仍在加载时,它将被隐藏并带有等待指示器)。相关代码如下:
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) 仍然是 nil。我虽然他们应该 non-nil 感谢 xib 的 IBOutlet...我错过了什么?
提前感谢您的帮助!
I have set up a custom class (subclass of UIView) to link a xib file
不,你没有。没有这样的 "link" 是可能的。
what am I missing?
你没有遗漏任何东西,因为你已经想通了!
只是凭空创建一个 LaunchCustomScreen 实例(即像您一样说 LaunchCustomScreen()
)只是创建此 class 的一个实例。它与 .xib (nib) 文件没有任何关系! class 和笔尖之间没有任何魔法 "link"!因此,没有任何事情会导致这些属性获得任何值。正如您正确解释的那样,它们是 nil
.
您已经在 nib 中设计并配置了 LaunchCustomScreen 的一个特殊实例。 那个是插座连接的实例,在同一个笔尖。因此,如果您想要一个带有连接插座的 LaunchCustomScreen 实例,您必须 加载 nib!加载 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 并准备好将其粘贴到您的界面中。由于视图来自笔尖,因此设置了它的出口,这就是您所追求的。您可以根据需要多次执行此操作,以获得任意多的此视图 "copies"。