如何解决每次调用 func 时增加属性观察器宽度
在我下面的 swift 代码中,当我使用 propertyObserver 添加另一个框时,滚动视图是固定的 我无法增加滚动视图。我希望每次将新项目添加到计数器时都会增加 scrollivew 的大小。我在下面添加了一个 gif 来显示问题所在。你可以看到新的空间没有添加到滚动视图中。
import UIKit
class PropertyObserverExmple {
var number: Int = 0 {
willSet(newNumber) {
print("About to change to \(newNumber)")
}
didSet(oldNumber) {
print("Just changed from \(oldNumber) to \(self.number)")
}
}
}
var observer = PropertyObserverExmple()
class SwipeableuIScrollView: UIScrollView {
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIButton || view is UILabel{
return true
}
return touchesShouldCancel(in: view)
}
}
class ViewController: UIViewController {
var scrollView:SwipeableuIScrollView!
var greenView:UIView!
var addMore:UIButton!
var leadingAnchor: NSLayoutXAxisAnchor!
var counter: Int? {
didSet {
for i in (oldValue ?? 0)..<(counter ?? 0){
let t_button = UIButton.init(frame: CGRect.zero)
t_button.translatesAutoresizingMaskIntoConstraints = false
t_button.backgroundColor = UIColor.blue
scrollView.addSubview(t_button)
NSLayoutConstraint.activate([
t_button.leadingAnchor.constraint(equalTo: leadingAnchor,constant:5.0),t_button.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor),t_button.heightAnchor.constraint(equalToConstant: 20),t_button.widthAnchor.constraint(equalToConstant: 75.0)
])
leadingAnchor = t_button.trailingAnchor
t_button.setTitle("Button \(i)",for: .normal)
}
}
}
var scrollViewHeightConstraint:NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
observer.number = 4
scrollView = SwipeableuIScrollView.init(frame: CGRect.zero)
scrollView.translatesAutoresizingMaskIntoConstraints = false
greenView = UIView.init(frame: CGRect.zero)
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.backgroundColor = UIColor.green
addMore = UIButton.init(frame: CGRect.zero)
addMore.translatesAutoresizingMaskIntoConstraints = false
addMore.backgroundColor = UIColor.orange
addMore.setTitle("add",for: .normal)
self.view.addSubview(scrollView)
self.view.addSubview(greenView)
self.view.addSubview(addMore)
addMore.addTarget(self,action: #selector(increaseC),for: .touchDown)
scrollViewHeightConstraint = NSLayoutConstraint.init(item: scrollView,attribute: .height,relatedBy: NSLayoutConstraint.Relation.equal,toItem: nil,attribute: .notAnAttribute,multiplier: 1.0,constant: 50.0)
NSLayoutConstraint.activate([
addMore.topAnchor.constraint(equalTo: self.view.topAnchor,constant: 50.0),addMore.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant: -15.0),addMore.heightAnchor.constraint(equalToConstant: 25.0),addMore.widthAnchor.constraint(equalToConstant: 100.0),scrollView.topAnchor.constraint(equalTo: self.addMore.bottomAnchor,constant: 10.0),scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),scrollViewHeightConstraint,greenView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor),greenView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor),greenView.topAnchor.constraint(equalTo: self.scrollView.bottomAnchor),greenView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor)
])
leadingAnchor = self.scrollView!.leadingAnchor
counter = 10
self.scrollView.trailingAnchor.constraint(equalTo: leadingAnchor).isActive = true
}
@objc func increaseC(){
counter! += 1
}
}
解决方法
不清楚你想用你的“PropertyObserver”做什么......
但是,有一个更简单的方法来完成这个......
- 添加一个
UIStackView
作为滚动视图的子视图 - 使用该堆栈视图来保存按钮
- 将堆栈视图限制为滚动视图的
Content Layout Guide
这是一个简单的例子:
class PropertyObserverExmple {
var number: Int = 0 {
willSet(newNumber) {
print("About to change to \(newNumber)")
}
didSet(oldNumber) {
print("Just changed from \(oldNumber) to \(self.number)")
}
}
}
var observer = PropertyObserverExmple()
class SwipeableUIScrollView: UIScrollView {
override func touchesShouldCancel(in view: UIView) -> Bool {
if view is UIButton || view is UILabel{
return true
}
return touchesShouldCancel(in: view)
}
}
class ScrollButtonsViewController: UIViewController {
// this will hold the buttons
var stackView: UIStackView!
var scrollView:SwipeableUIScrollView!
var greenView:UIView!
var addMore:UIButton!
var leadingAnchor: NSLayoutXAxisAnchor!
var counter: Int? {
didSet {
for i in (oldValue ?? 0)..<(counter ?? 0) {
let t_button = UIButton()
t_button.translatesAutoresizingMaskIntoConstraints = false
t_button.backgroundColor = UIColor.blue
// add it to the stack view,not the scroll view
//scrollView.addSubview(t_button)
stackView.addArrangedSubview(t_button)
NSLayoutConstraint.activate([
t_button.heightAnchor.constraint(equalToConstant: 20),t_button.widthAnchor.constraint(equalToConstant: 75.0)
])
t_button.setTitle("Button \(i)",for: .normal)
}
}
}
var scrollViewHeightConstraint:NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
observer.number = 4
scrollView = SwipeableUIScrollView.init(frame: CGRect.zero)
scrollView.translatesAutoresizingMaskIntoConstraints = false
greenView = UIView.init(frame: CGRect.zero)
greenView.translatesAutoresizingMaskIntoConstraints = false
greenView.backgroundColor = UIColor.green
addMore = UIButton.init(frame: CGRect.zero)
addMore.translatesAutoresizingMaskIntoConstraints = false
addMore.backgroundColor = UIColor.orange
addMore.setTitle("add",for: .normal)
addMore.setTitleColor(.white,for: .normal)
addMore.setTitleColor(.black,for: .highlighted)
self.view.addSubview(scrollView)
self.view.addSubview(greenView)
self.view.addSubview(addMore)
addMore.addTarget(self,action: #selector(increaseC),for: .touchDown)
// respect safe area
let g = view.safeAreaLayoutGuide
scrollViewHeightConstraint = scrollView.heightAnchor.constraint(equalToConstant: 50.0)
NSLayoutConstraint.activate([
addMore.topAnchor.constraint(equalTo: g.topAnchor,constant: 50.0),addMore.trailingAnchor.constraint(equalTo: g.trailingAnchor,constant: -15.0),addMore.heightAnchor.constraint(equalToConstant: 25.0),addMore.widthAnchor.constraint(equalToConstant: 100.0),scrollView.topAnchor.constraint(equalTo: self.addMore.bottomAnchor,constant: 10.0),scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor),scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor),scrollViewHeightConstraint,greenView.leadingAnchor.constraint(equalTo: g.leadingAnchor),greenView.trailingAnchor.constraint(equalTo: g.trailingAnchor),greenView.topAnchor.constraint(equalTo: self.scrollView.bottomAnchor),greenView.bottomAnchor.constraint(equalTo: g.bottomAnchor)
])
stackView = UIStackView()
stackView.axis = .horizontal // the default,but just for clarity
stackView.distribution = .fill // the default,but just for clarity
stackView.alignment = .center
stackView.spacing = 5
stackView.translatesAutoresizingMaskIntoConstraints = false
// add the stack view to the scroll view
scrollView.addSubview(stackView)
// constrain the stack view
// this will ALSO define the "scrollable" area
NSLayoutConstraint.activate([
// constrain stack view to scroll view's Content Layout Guide
stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),stackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),// constrain stack view height to scroll view's Frame Layout Guide
stackView.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor),])
counter = 10
}
@objc func increaseC(){
counter! += 1
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。