Ios 自定义UINavigationBar的外观
我对iOS UI设计还不熟悉,我正在编写代码来显示高度定制的导航栏,这将用于我的交通应用程序 以下是我的导航栏的功能(请参见下图):Ios 自定义UINavigationBar的外观,ios,swift,user-interface,uikit,Ios,Swift,User Interface,Uikit,我对iOS UI设计还不熟悉,我正在编写代码来显示高度定制的导航栏,这将用于我的交通应用程序 以下是我的导航栏的功能(请参见下图): Layout Margins为18,其子视图之间的Space为9 它的所有子视图“height都是44,所有UIBarButtonItem都是矩形 backBarButtonItem的位置应与leftBarButtonItem相同 在正常状态下,其高度为80 在展开状态下(例如地图应用程序中的方向字段视图),其标题视图将包含两个UITextFields,因此其高
Layout Margins
为18
,其子视图之间的Space
为9
height
都是44
,所有UIBarButtonItem
都是矩形backBarButtonItem
的位置应与leftBarButtonItem
相同高度
为80
标题视图
将包含两个UITextField
s,因此其高度
应为136
UINavigationBar
的子类,并使用Identity Inspector将自定义类连接到故事板中的导航栏
对象。然而,我不知道从哪里开始。虽然现在我重写了sizehatfits(usize:)
函数以使其高度
变长,但子视图接近底部。我找不到像谷歌地图、优步等定制UINavigationBar
的最佳实践
如何通过子类化
UINavigationBar
实现这样的导航栏?或者还有其他解决方案吗?您可以通过以下步骤将UINavigationBar子类化
override func sizeThatFits(_ size: CGSize) -> CGSize {
var bound = super.sizeThatFits(size)
bound.height += sizeToAdd //The height you want
return bound
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
//If you don't override this function and do as follows, you'll
//find that all NavigationButtons and the Title positioned at the
//bottom of your navigation bar.(for the Title, we still need to
//add one line in setup())
let classes = ["UIButton", "UINavigationItemView",
"UINavigationButton"]
for object in self.subviews{
let classOfObject = String(describing: type(of: object))
if classes.contains(classOfObject){
var objectFrame = object.frame
objectFrame.origin.y -= self.sizeToAdd
object.frame = objectFrame
}
}
}
YOURVIEW.frame = CGRect(x: 0, y: 44, width:
(self.navigationController?.navigationBar.bounds.width)!, height:
(self.navigationController?.navigationBar.bounds.height)! +
self.sizeToAdd)//The height
self.navigationController?.navigationBar.
addSubview(YOURVIEW)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if(!(self.navigationController?.navigationBar.subviews.contains
(YOURVIEW))!){ //Either get it working with setting a tag to
//your view and checking it against all subviews
//if you haven't use XIB
self.navigationController?.navigationBar.
addSubview(YOURVIEW)
}else {
UIView.transition(with: YOURVIEW,
duration: 0.5, options: [ANYOPTIONS], animations: {
self.profileNavigationView.alpha = 1.0
}) { (success) in
}
}
}
}不建议使用子类化
UINavigationBar
。你应该探索UIAppearance
类以获得所需的UI。我喜欢上面的设计截图,你是如何制作的?为什么不使用一个简单的视图并向其中添加所需的子视图?在我看来,这是做你想做的事情更简单有效的方法。@Adeel谢谢!但是,当我按下/弹出另一个导航项时,子视图仍保持不变。您可以共享屏幕截图或其他内容吗?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if(!(self.navigationController?.navigationBar.subviews.contains
(YOURVIEW))!){ //Either get it working with setting a tag to
//your view and checking it against all subviews
//if you haven't use XIB
self.navigationController?.navigationBar.
addSubview(YOURVIEW)
}else {
UIView.transition(with: YOURVIEW,
duration: 0.5, options: [ANYOPTIONS], animations: {
self.profileNavigationView.alpha = 1.0
}) { (success) in
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
UIView.transition(with: YOURVIEW, duration:
0.5,
options: [ANYOPTIONS], animations: {
self.profileNavigationView.alpha = 0.0
}) { (success) in
//remove it here if you want
}