- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 Swift 5.1.3、iOS13.3、XCode11.3,
我尝试创建一个简单的按钮目标操作。
但是,Button 位于其自己的 StackView 类中,而且是一个惰性按钮。
为什么目标操作在我的代码中不起作用?即 callButtonMethod
永远不会被调用!
可能是因为 API 响应较晚,还是因为惰性按钮无法执行目标操作。我现在一无所知。
感谢您对此提供的任何帮助。
这是我的代码:
class CockpitHeaderStackView: UIStackView {
weak var profileBtnDelegate: CallButtonProfileImage?
var profileImageView = UIImageView()
var profileName = "Cockpit".localized
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
if let profile = MyAPI.profile, let person = profile.person {
profileName = "\(person.firstName ?? "") \(person.lastName ?? "")"
}
MyAPI.getPicture(PictureType.avatar) { [weak self] (error, image) in
guard let self = self else { return } // check if self still alive otherwise bail out
DispatchQueue.main.async {
if let image = image {
self.profileImageView.image = image
} else {
self.profileImageView.image = #imageLiteral(resourceName: "profile-placeholder-small")
}
self.profileImageView.contentMode = .scaleAspectFill
self.axis = .horizontal
self.alignment = .bottom
self.spacing = 10.0
self.addArrangedSubview(self.titleLabel)
self.addArrangedSubview(self.button)
}
}
}
lazy var titleLabel: UILabel = {
let labelWidth: CGFloat = UIScreen.main.bounds.width - 16.0 - 10.0 - 36.0 - 16.0 // FullScreenWidth minus (Leading + Spacing + ButtonWidth + Trailing)
let label = UILabel()
label.font = AppConstants.Font.NavBar_TitleFont
label.text = profileName
label.textColor = .white
label.tintColor = .white
label.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var button: UIButton = {
let buttonWidth: CGFloat = 36.0
let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: buttonWidth, height: buttonWidth)))
button.setImage(self.profileImageView.image, for: .normal)
button.addTarget(self, action: #selector(callButtonMethod), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
button.layer.cornerRadius = button.frame.size.width / 2
button.layer.masksToBounds = false
button.clipsToBounds = true
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonWidth).isActive = true
return button
}()
@objc func callButtonMethod() {
profileBtnDelegate?.callProfileBtnMethod()
}
}
CockpitHeaderStackView
用于创建我的 ViewController 的自定义导航栏。
这里是使用 CockpitHeaderStackView
的自定义导航栏的代码:
protocol CallButtonProfileImage: AnyObject {
func callProfileBtnMethod()
}
class MyViewController: UIViewController {
// ...
lazy var titleStackView: CockpitHeaderStackView = {
let titleStackView = CockpitHeaderStackView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 88.0)))
titleStackView.translatesAutoresizingMaskIntoConstraints = false
return titleStackView
}()
lazy var cockpitHeaderView: UIView = {
let cockpitHeaderView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: view.bounds.width, height: 88.0)))
cockpitHeaderView.addSubview(titleStackView)
titleStackView.leadingAnchor.constraint(equalTo: cockpitHeaderView.leadingAnchor, constant: 16.0).isActive = true
titleStackView.topAnchor.constraint(equalTo: cockpitHeaderView.topAnchor).isActive = true
titleStackView.trailingAnchor.constraint(equalTo: cockpitHeaderView.trailingAnchor, constant: -16.0).isActive = true
titleStackView.bottomAnchor.constraint(equalTo: cockpitHeaderView.bottomAnchor).isActive = true
return cockpitHeaderView
}()
override func viewDidLoad() {
super.viewDidLoad()
// ...
view.clipsToBounds = true
navigationController?.set_iOS12_lookAndFeel()
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationItem.largeTitleDisplayMode = .always
}
override func viewWillLayoutSubviews() {
// replace NavBar title by custom cockpitHeaderView
self.title = ""
self.navigationItem.titleView = self.cockpitHeaderView
// position the cockpitHeaderView inside the largeTitleDisplayMode NavBar
self.cockpitHeaderView.translatesAutoresizingMaskIntoConstraints = false
self.cockpitHeaderView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
if let navBarBottomAnchor = self.navigationController?.navigationBar.bottomAnchor {
if UIScreen.main.bounds.height > 568.0 {
self.cockpitHeaderView.topAnchor.constraint(equalTo: navBarBottomAnchor, constant: -48.0).isActive = true
} else {
self.cockpitHeaderView.topAnchor.constraint(equalTo: navBarBottomAnchor, constant: -46.0).isActive = true // iPhone SE space limitation
}
} else {
self.cockpitHeaderView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 89.0).isActive = true
}
}
func callProfileBtnMethod() {
print("right BarButton called here")
}
}
最佳答案
我终于找到了“解决方案”:惰性初始化似乎是错误行为的原因。
事实上,当我替换所有惰性初始化并消除 StackView(称为 CockpitHeaderStackView
)并将所有内容放入非惰性 let 常量中时,它就可以工作了!!
这是最终的相关代码(即我将所有内容都放在 viewWillAppear
方法中):
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let cardsHorizontalController = CardsHorizontalController()
self.view.addSubview(cardsHorizontalController.view)
cardsHorizontalController.view.translatesAutoresizingMaskIntoConstraints = false
cardsHorizontalController.view.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100.0).isActive = true
cardsHorizontalController.view.heightAnchor.constraint(equalToConstant: 279).isActive = true
cardsHorizontalController.view.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
navigationController?.set_iOS12_lookAndFeel()
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationItem.largeTitleDisplayMode = .always
PeaxAPI.getPicture(PictureType.avatar) { [weak self] (error, image) in
guard let self = self else { return } // check if self still alive otherwise bail out
DispatchQueue.main.async {
if let image = image {
self.profileImageView.image = image
} else {
self.profileImageView.image = #imageLiteral(resourceName: "profile-placeholder-small")
}
self.profileImageView.contentMode = .scaleAspectFill
if let profile = PeaxAPI.profile, let person = profile.person {
self.profileName = "\(person.firstName ?? "") \(person.lastName ?? "")"
}
let titleStackView = UIStackView(frame: CGRect(origin: .zero, size: CGSize(width: self.view.bounds.width, height: 88.0)))
titleStackView.isUserInteractionEnabled = true
titleStackView.translatesAutoresizingMaskIntoConstraints = false
titleStackView.axis = .horizontal
titleStackView.alignment = .bottom
titleStackView.spacing = 10.0
let labelWidth: CGFloat = UIScreen.main.bounds.width - 16.0 - 10.0 - 36.0 - 16.0 // FullScreenWidth minus (Leading + Spacing + ButtonWidth + Trailing)
let label = UILabel()
label.font = AppConstants.Font.NavBar_TitleFont
label.text = self.profileName
label.textColor = .white
label.tintColor = .white
label.widthAnchor.constraint(equalToConstant: labelWidth).isActive = true
label.translatesAutoresizingMaskIntoConstraints = false
let buttonWidth: CGFloat = 36.0
let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: buttonWidth, height: buttonWidth)))
button.setImage(self.profileImageView.image, for: .normal)
button.isUserInteractionEnabled = true
button.addTarget(self, action: #selector(self.callProfileBtnMethod), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
button.layer.cornerRadius = button.frame.size.width / 2
button.layer.masksToBounds = false
button.clipsToBounds = true
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: buttonWidth).isActive = true
button.heightAnchor.constraint(equalToConstant: buttonWidth).isActive = true
titleStackView.addArrangedSubview(label)
titleStackView.addArrangedSubview(button)
let cockpitHeaderView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: self.view.bounds.width, height: 88.0)))
cockpitHeaderView.isUserInteractionEnabled = true
cockpitHeaderView.addSubview(titleStackView)
titleStackView.leadingAnchor.constraint(equalTo: cockpitHeaderView.leadingAnchor, constant: 16.0).isActive = true
titleStackView.topAnchor.constraint(equalTo: cockpitHeaderView.topAnchor).isActive = true
titleStackView.trailingAnchor.constraint(equalTo: cockpitHeaderView.trailingAnchor, constant: -16.0).isActive = true
titleStackView.bottomAnchor.constraint(equalTo: cockpitHeaderView.bottomAnchor).isActive = true
// replace NavBar title by custom cockpitHeaderView
self.title = ""
self.navigationItem.titleView = cockpitHeaderView
cockpitHeaderView.sizeToFit()
}
}
}
关于swift - 惰性按钮的目标操作不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59773450/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!