Swift-一种强制重新绘制UIScrollView的方法



我有一个UIViewController,其中有一个UIScrollView,还有一个函数(build()(在UIScrollView中绘制UIView

问题:UIViewController中没有显示任何内容,但当我滚动时(因此当我更新UIScrollView时(,会显示我想要的UIView

我尝试了setNeedsDisplay()来强制重绘,但它不起作用。。。

帮助您理解问题的视频:https://vimeo.com/user87689481/review/281597574/3cccb78dc1

这是UIViewController:的代码

import UIKit
class MainViewController: UIViewController {
@IBOutlet weak var body: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationItem.largeTitleDisplayMode = .always
DispatchQueue.global(qos: .background).async {
while !Home.accessories.isInitialized {}
DispatchQueue.main.async {
self.build(Home.accessories.toUIView())
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
public func build(_ s: [UISectionView]) {
let topMargin = 10
let rightMargin = 10
let leftMargin = 10
let space = 5
let heightItem = 60
var b = topMargin
for t in s {
if t.isHidden == true {
continue
}
if t.title != nil {
let f = UIFont(name: "Helvetica", size: 20)
let l = UILabel(frame: CGRect(x: rightMargin, y : b, width: Int(UIScreen.main.bounds.width) - (rightMargin + leftMargin), height: Int(f!.lineHeight)))
l.font = f
l.text = t.title
body.addSubview(l)
b = b + Int(f!.lineHeight) + space
}
for i in t.items {
body.addSubview(i.getView(frame: CGRect(x: rightMargin, y: b, width: Int(UIScreen.main.bounds.width) - (rightMargin + leftMargin), height: heightItem), view: self))
b = b + heightItem + space
}
}
body.contentSize = CGSize(width: UIScreen.main.bounds.width, height: CGFloat(b))
//a code to force body (UIScrollView) to refresh/relaod/redraw/update/...
}
}

我希望我们能帮我

提前感谢!

没有重新绘制UIScrollView的方法,那么您只需要做一件事:

  1. 将视图添加到UIScrollView
  2. 设置UIScrollViewcontentSize,以便用户可以四处平移并查看UIScrollView的所有内容

您在代码中所做的似乎是可以的,因为您正在做上面列出的两件事。

问题是,如果您的t被隐藏:

if t.isHidden == true {
continue
}

或者您正在后台线程的其他地方调用build()方法

为了确保你没有这样做,你可以在build()方法中添加assert(Thread.isMainThread, "Never call me on background thread")作为第一行

最新更新