gpt4 book ai didi

ios - 自定义导航栏项目放置不当

转载 作者:搜寻专家 更新时间:2023-10-31 22:01:50 26 4
gpt4 key购买 nike

我有一个自定义导航栏子类:

class ProfileNavigationBar: UINavigationBar {

var titleLabel: UILabel
var backButton: UIBarButtonItem
var friendsButton: FriendsButton?

required init?(coder: NSCoder) {
titleLabel = UILabel(frame: CGRect(x: 0, y: 40, width: 320, height: 40))
backButton = UIBarButtonItem.backButton(nil, action: nil)
friendsButton = FriendsButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24))
super.init(coder: coder)
}

override func awakeFromNib() {
super.awakeFromNib()

let item = UINavigationItem()
item.titleView = titleLabel

item.leftBarButtonItem = backButton
item.hidesBackButton = true

let friendsItem = UIBarButtonItem(customView: friendsButton!)
item.rightBarButtonItems = [friendsItem]

pushItem(item, animated: false)
}

}

当 FriendsButton 的状态属性发生变化时,FriendsButton 会自行调整大小。

问题是当 View 第一次加载时,它看起来像这样,后退按钮和 FriendsButton 就在导航栏的边缘:(.loading state)

enter image description here

但是,当我将 FriendsButton 状态更改为 .add 时,它通常显示如下:

enter image description here

我该如何解决这个问题?

下面是 FriendsButton 的实现:

class FriendsButton: UIView {

var state: FriendsButtonState {
didSet {
style(selected: state)
}
}

var title: String = "" {
didSet {
set(title: title)
}
}

var font = UIFont.boldSystemFont(ofSize: 11)

private var imageView: UIImageView!
private var button: UIButton!
var loading: UIActivityIndicatorView!

init(frame: CGRect, state: FriendsButtonState = .loading) {
self.state = state
super.init(frame: frame)
backgroundColor = .yellow

let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
imageView = UIImageView(frame: CGRect(x: plusYValue*2, y: plusYValue, width: plusSize, height: plusSize))
imageView.contentMode = .scaleAspectFit
addSubview(imageView)

let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button = UIButton(frame: CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height))
addSubview(button)

loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
addSubview(loading)

style(selected: state)

updateSize()
}

func addTarget(object: Any, selector: Selector) {
button.addTarget(object, action: selector, for: .touchUpInside)
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
loading.startAnimating()
loading.isHidden = state != .loading
isHidden = false

switch state {
case .friends:
backgroundColor = .black
button.setTitleColor(.white, for: .normal)
imageView.image = #imageLiteral(resourceName: "friends-tick")
title = "Friends"
// ... + all other cases
}
self.updateSize()
}

private func configureBorder(state: FriendsButtonState) {
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = state == .loading ? 0 : 1
layer.cornerRadius = 5
}

private func set(title: String) {
let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
button.titleLabel?.font = font
button.setTitle(title, for: .normal)
button.frame = CGRect(x: plusYValue*3.5 + plusSize, y: 0, width: titleSize.width, height: frame.size.height)
self.updateSize()
}

private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
return
}

let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}

编辑: 我最初尝试将按钮设置为 .add 状态,但它仍然会出现在导航栏的最右侧,直到它被更改为其他状态。似乎按钮的第一个状态总是使导航栏将其所有子项移动到框架的边缘,直到它被更新。

编辑:我无法通过复制相关代码在另一个项目上重现该问题,但这是我遇到的具体问题(如下图所示)。第一次导航到 View 时,导航栏边缘和后退按钮之间的间隙不会保持不变(我设法在导航推送动画中途获得了屏幕截图)。我现在的问题是,这可能是什么原因造成的?

enter image description here

最佳答案

您必须停止事件指示器,否则它不会自行隐藏:

private func style(selected: FriendsButtonState) {
configureBorder(state: selected)
if (state == .loading) {
loading.startAnimating()
} else {
loading.stopAnimating()
}
loading.isHidden = state != .loading

顺便说一句:如果您将 UIActivityIndi​​catorView 配置为在停止时隐藏自身,您也可以跳过 loading.isHidden = state != .loading:

init(frame: CGRect, state: FriendsButtonState = .loading) {
// ...

loading = UIActivityIndicatorView(activityIndicatorStyle: .gray)
loading.center = center
loading.hidesWhenStopped = true
addSubview(loading)
// ...
}

正确布置右侧导航栏按钮,您必须修改FriendsButton.updateSize:当处于.loading 状态时 - 至少第一次 - 您还必须更新框架。

private func updateSize() {
if state == .loading {
frame.size.width = frame.size.width
loading.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
loading.startAnimating()
// do not return here
}

let plusSize = frame.size.height/2
let plusYValue = (frame.size.height-plusSize)/2
let titleSize = (title as NSString).size(attributes: [NSFontAttributeName : font])
let totalWidth = plusYValue*5.5 + plusSize + titleSize.width
frame.size.width = totalWidth
}

我假设左键也一样,但不幸的是你的代码没有在这里编译(在 init? 方法中调用时出错 backButton = UIBarButtonItem.backButton(nil, action: nil),因为 UIBarButtonItem

上没有静态成员 backButton

现在,it works on my machine :

应用启动后: Just after start of the app

状态更改为 .friends 后 After state change to .friends

状态再次变回.loading State changed back again to .loading

一切都很好对齐,没有变化等。如果这不适用于您的项目,那么可能还有其他方面您没有随代码一起发布。

关于ios - 自定义导航栏项目放置不当,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41751495/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com