setneedsdisplay layoutifneeded setNeedsLayout

本文深入探讨了iOS中view的重绘与布局刷新机制,包括setNeedsDisplay、setNeedsLayout和layoutIfNeeded的区别与使用场景,解析了这些方法如何影响UI的绘制与布局更新。
部署运行你感兴趣的模型镜像

1、setneedsdisplay : 用于 view 的重绘操作,会触发 view 的 drawRect: 方法。

2、setNeedsLayout 和 layoutIfNeeded 区别

  • setNeedsLayout
    标记为需要重新布局,异步调用layoutIfNeeded 刷新布局,不立即刷新,在下一轮runloop结束前刷新,对于这一轮runloop之内的所有布局和UI上的更新只会刷新一次,layoutSubviews一定会被调用。
  • layoutIfNeeded
    如果有需要刷新的标记,立即调用layoutSubviews进行布局(如果没有标记,不会调用layoutSubviews)。

 

【注】下面才会立即刷新布局 ( layoutSubviews )

[self setNeedsLayout];
[self layoutIfNeeded];

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

帮我修改这些地方: private lazy var scrollView: DeviceListMasterMultiResponseScrollView = { guard !showLocalDeviceOnly else { return DeviceListMasterMultiResponseScrollView() } let scrollView = DeviceListMasterMultiResponseScrollView() scrollView.bounces = false scrollView.isScrollEnabled = true scrollView.allowPanDownToShowSearchBar = allowPanDownToShowSearchBar scrollView.showsVerticalScrollIndicator = false scrollView.delegate = self scrollView.backgroundColor = .clear scrollView.contentInset = UIEdgeInsets.zero scrollView.addSubview(scrollViewContainerView) return scrollView }() private lazy var scrollViewContainerView: UIView = { guard !showLocalDeviceOnly else { return UIView() } let scrollViewContainerView = UIView() scrollViewContainerView.backgroundColor = .clear scrollViewContainerView.addSubview(headerSearchView) scrollViewContainerView.addSubviews([tabBarContainer]) // 注意:SnapKit 约束不需要改,它们是基于 Auto Layout 的 headerSearchView.snp.makeConstraints { make in make.top.equalToSuperview().offset(10) make.height.equalTo(62) make.leading.trailing.equalToSuperview() } tabBarContainer.snp.makeConstraints { make in make.top.equalTo(headerSearchView.snp.bottom) make.height.equalTo(tabCollectionHeightConstant.constant) make.leading.equalToSuperview() make.trailing.equalToSuperview() } return scrollViewContainerView }() override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() guard !showLocalDeviceOnly else { return } // 安全获取导航栏底部 let top: CGFloat = navigationController?.navigationBar.frame.maxY ?? 0 // ✅ 使用 tabBar.isHidden 而不是 isTabBarHidden(兼容 iOS < 18) let tabBar = tabBarController?.tabBar let isTabBarHidden = tabBar?.isHidden ?? true let tabBarHeight = tabBar?.frame.height ?? 0 let safeBottom = view.safeAreaInsets.bottom // 只有当 TabBar 存在且未被隐藏时才加上它的高度 let bottom = !isTabBarHidden ? (tabBarHeight + safeBottom) : safeBottom let width = view.bounds.width let visibleHeight = view.bounds.height - top - bottom let contentHeight = visibleHeight + nameLabelViewHeight + 62 // 避免重复设置相同的 frame if scrollView.frame != CGRect(x: 0, y: top, width: width, height: visibleHeight) { scrollView.frame = CGRect(x: 0, y: top, width: width, height: visibleHeight) scrollView.contentSize = CGSize(width: width, height: contentHeight) scrollViewContainerView.frame = CGRect(x: 0, y: 0, width: width, height: contentHeight) // 可选:强制刷新显示 scrollView.setNeedsDisplay() } } 以及viewdidload里的 @objc private func orientationDidChange() { DispatchQueue.main.async { // 强制重新计算所有布局 self.view.setNeedsLayout() self.view.layoutIfNeeded() // 立即执行 layout } } override func viewDidLoad() { super.viewDidLoad() // 开启设备方向通知 UIDevice.current.beginGeneratingDeviceOrientationNotifications() // 监听方向改变 NotificationCenter.default.addObserver( self, selector: #selector(orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil )
10-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值