我是iOS UI设计的新手,我正在编写显示高度自定义导航栏的代码,该导航栏将用于我的运输应用程序。
以下是我导航栏的功能(见下图):
Layout Margins
为18
,其子视图之间的Space
为9
。height
均为44
,所有UIBarButtonItem
均为矩形。backBarButtonItem
的位置应与leftBarButtonItem
相同。height
为80
。titleView
将包含两个UITextField
,因此其{ {1}}应为height
。请参阅Real Design Screenshots
所以我已经声明了136
的子类,并使用Identity Inspector将自定义类连接到故事板中的UINavigationBar
对象。但是,我不知道从哪里开始。虽然我现在超越Navigation Bar
函数使其sizeThatFits(_ size:)
长,但是子视图接近底部。我找不到自定义height
的最佳做法,例如谷歌地图,优步等。
如何通过继承UINavigationBar
来实现此类导航栏?或者还有其他解决方案吗?
答案 0 :(得分:2)
您可以使用以下步骤继承UINavigationBar ..
添加一个新类(UINavigationBar的子类),选择ViewController的NavigationController。从文档大纲中选择ViewController导航栏。将班级设置为自定义班级。
在您的自定义类中,执行以下操作..
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
}
}
}
现在在setup()中添加以下代码,以便按照人们想要的方式提升标题(通常!)
func setup() -> Void {
self.setTitleVerticalPositionAdjustment(-self.sizeToAdd, for:
.default)
}
现在,您可以根据需要设计视图(这里,我已经使用XIB加载了自定义视图,您也可以使用代码。)并将其作为子视图添加到导航栏中,在ViewController中。例如,在viewDidLoad ..
中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)
因此,您可以通过这种方式对导航栏进行子类化。但是当你将任何其他viewController推到这个上时,你会看到(如果你还没有将另一个NavigationController嵌入到你正在推动的viewController中),那么视图仍然保持在推送的viewController中。您可以在推送任何其他viewController之前将其从超级视图中删除。只是删除它将无法提供良好的用户体验,因为其他系统元素(如果有的话)将很好地淡出。因此,请执行以下操作以提供良好的用户体验...
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
}
}