【问题标题】:UIView frames change every-time upon ViewController loading每次加载 ViewController 时,UIView 框架都会更改
【发布时间】:2021-01-14 10:46:20
【问题描述】:

我在 xib 上有一个 UIView,当我在 viewDidLoad 上检查它的框架时,它说:

  - some : <UIView: 0x7fcc3948b8a0; frame = (56.3333 122; 262.333 262.333); clipsToBounds = YES; autoresize = RM+BM; layer = <CALayer: 0x600003a62060>>

在调用layoutIfNeeded()之后,就在上一个日志之后,它说:

  - some : <UIView: 0x7fcc3948b8a0; frame = (56.5 121.917; 262 262.5); clipsToBounds = YES; autoresize = RM+BM; layer = <CALayer: 0x600003a62060>>

并且,在viewDidLayoutSubviews(),框架是:

  - some : <UIView: 0x7fcc3948b8a0; frame = (62 122; 290 289.5); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x600003477420>; layer = <CALayer: 0x600003a62060>>

为什么这对我很重要?因为我在该视图内设置了一个UIScrollView,并在UIScrollView 内设置了一个带有缩放功能的UIImage,这使得图像正确的缩放框架被打破。

我该如何解决这个问题?

【问题讨论】:

  • 您需要更详细地了解自己在做什么。您“在 xib 上有一个 UIView” ...显示您如何约束该视图以及如何加载并将其添加为子视图。 "on viewDidLoad" ...您的意思是在控制器中添加了来自 xib 的视图吗?还是您的 xib 是视图控制器?您如何尝试“在该视图内设置 UIScrollView 并在 UIScrollView 内设置缩放的 UIImage”
  • 在我的 UIViewController 中,我添加了一个 UIView (1),它有一个顶部、对齐中心 x、等宽(到 superview)和比率 1:1 的约束。他有一个 UIScrollView 作为子视图,它有一个顶部、底部、前导和尾随约束。这个 UIScrollView 有一个 UIView 设置为子视图,他有顶部、底部、前导、尾随和相等的宽度、高度(到 UIView num.1)约束。在这个 UIView 里面我有一个没有任何约束的 UIImage 。啤酒花这个可以理解。哈哈
  • 为什么不给 UIImageView 添加约束?
  • 因为图像是由我从 WS 获得的数据缩放的,并且在向它添加约束时,它会阻止它被缩放。 UIScrollViewDelegate 有一个名为“viewForZooming”的方法,我返回图像并缩放图像。

标签: ios swift uiscrollview uiimage constraints


【解决方案1】:

这是一个非常简单的例子,可以帮助你。

我有一个1200 x 1200 图像,网格线为 100 像素。绿色矩形位于600, 200 并且是300 x 400 像素。那将是我的目标“缩放到”矩形。

当然,我的滚动视图不会有精确的3:4 比率,因此绿色矩形最终会在缩放时位于滚动视图的中心。

这是在 iPhone 11 Pro Max 上。我正在使用导航控制器,所以您会在顶部看到导航栏...视图背景为白色...滚动视图被限制在视图的安全区域,每侧有 8 个点:

这是生成该代码的代码:

class ScrollTestViewController : UIViewController, UIScrollViewDelegate {
    
    let scrollView: UIScrollView = {
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    }()
    
    let zoomImageView: UIImageView = {
        let v = UIImageView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.contentMode = .scaleToFill
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let img = UIImage(named: "img1200x1200") else {
            fatalError("Could not load image!!!")
        }
        print(img.size)
        zoomImageView.image = img
        
        view.backgroundColor = .white
        
        // add the scroll view
        self.view.addSubview(scrollView)
        
        // add contentView to scroll view
        scrollView.addSubview(zoomImageView)
        
        // respect safe-area
        let g = view.safeAreaLayoutGuide
        
        // we're going to constrain the zoomImageView to the scroll view's content layout guide
        let scg = scrollView.contentLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // constrain scrollView Top / Leading / Trailing / Bottom to view (safe-area)
            //  with 8-pts on each side
            scrollView.topAnchor.constraint(equalTo: g.topAnchor, constant: 8.0),
            scrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 8.0),
            scrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
            scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -8.0),
            
            // constrain zoomImageView Top / Leading / Trailing / Bottom to scroll view's Content Layout Guide
            zoomImageView.topAnchor.constraint(equalTo: scg.topAnchor, constant: 0.0),
            zoomImageView.leadingAnchor.constraint(equalTo: scg.leadingAnchor, constant: 0.0),
            zoomImageView.trailingAnchor.constraint(equalTo: scg.trailingAnchor, constant: 0.0),
            zoomImageView.bottomAnchor.constraint(equalTo: scg.bottomAnchor, constant: 0.0),

            // constrain zoomImageView's width and height to the width and height of the image
            zoomImageView.widthAnchor.constraint(equalToConstant: img.size.width),
            zoomImageView.heightAnchor.constraint(equalToConstant: img.size.height),
            
        ])
        
        scrollView.minimumZoomScale = 0.25
        scrollView.maximumZoomScale = 10.0

        scrollView.delegate = self

    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // we need to set the "zoom to" rect *after* auto-layout
        //  has finished everything else
        let r = CGRect(x: 600, y: 200, width: 300, height: 400)
        scrollView.zoom(to: r, animated: false)
    }
    
    func viewForZooming(in scrollView: UIScrollView) -> UIView? {
        return zoomImageView
    }
    
}

【讨论】:

  • 你介意私下帮我解决这个问题,然后当然发布解决方案吗?
  • 它可以工作,但由于某种原因,在 iPhone 6s 中,与其他设备相比,滚动条内的图像更小,可能是什么问题?
  • @YossiTsafar - 你必须更清楚一点......这是我在 iPhone 6s(模拟器)上运行它时的样子:i.stack.imgur.com/PLKgU.png
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
相关资源
最近更新 更多