垂直旋转的 UIPageControl 占用太多空间

问题描述

我使用 CGAffineTransform 垂直旋转水平 UIPageControl。但是当我在我的收藏视图之外添加它时,它占用了太多的宽度。当我在其上添加宽度锚点时,UIPageControl 消失。

noticesPagingIndicator = UIPageControl()
let angle = CGFloat.pi/2
noticesPagingIndicator.transform = CGAffineTransform(rotationAngle: angle)
 NSLayoutConstraint.activate([
//            noticesPagingIndicator.widthAnchor.constraint(equalToConstant: 30),noticesPagingIndicator.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),noticesPagingIndicator.centerYAnchor.constraint(equalTo: noticesCollectionView.centerYAnchor),noticesCollectionView.leadingAnchor.constraint(equalTo: noticesPagingIndicator.trailingAnchor),noticesCollectionView.topAnchor.constraint(equalTo: noticeStackView.bottomAnchor,constant: 8),noticesCollectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: -8),noticesCollectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
 ])

page control taking too much width

当我查看 UIView 层次结构时,我看到 UIPageControl 上有很多填充

UI view hierarchy with too much width for page controller

启用宽度锚点:

enter image description here

with width anchor

解决方法

了解 Debug View Hierarchy 工具。它可以帮助您解决大多数布局问题。

当您转换视图时,它不会改变其边界,因此不会改变其与其他 UI 元素的约束关系。

使用此代码(8 页,所以 8 个点):

class ViewController: UIViewController {
    
    let pgc = UIPageControl()
    let greenLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemYellow
        
        pgc.translatesAutoresizingMaskIntoConstraints = false
        greenLabel.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(pgc)
        view.addSubview(greenLabel)
        
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // page control Leading to safe area Leading + 20,centerY
            pgc.leadingAnchor.constraint(equalTo: g.leadingAnchor,constant: 20.0),pgc.centerYAnchor.constraint(equalTo: g.centerYAnchor,constant: 0.0),// constrain greenLabel Leading to page control trailing + 8 and centerY,safe area trailing -8
            greenLabel.leadingAnchor.constraint(equalTo: pgc.trailingAnchor,constant: 8.0),greenLabel.centerYAnchor.constraint(equalTo: pgc.centerYAnchor),greenLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor,constant: -8.0),])

        // rotate the page control
        let angle = CGFloat.pi/2
        pgc.transform = CGAffineTransform(rotationAngle: angle)
        
        pgc.backgroundColor = .systemBlue
        greenLabel.backgroundColor = .green
        
        pgc.numberOfPages = 8
        
        greenLabel.numberOfLines = 0
        greenLabel.text = "UIPageControl indicates the number of open pages in an application by displaying a dot for each open page. The dot that corresponds to the currently viewed page is highlighted. UIPageControl supports navigation by sending the delegate an event when a user taps to the right or to the left of the currently highlighted dot."
        
    }
    
}

你得到这个输出:

enter image description here

如您所见,页面控件尾随锚点的绿色标签引导约束显示页面控件宽度与没有旋转的情况相匹配。

如果您使用 Debug View Hierarchy 检查视图,您将看到页面控件如下所示:

enter image description here

框架w: 27.5 h: 217,但边界w: 217 h: 27.5

要解决此问题,您需要将页面控件嵌入到“holder”视图中,将 holder 视图的 Height 限制为页面控件的 Width 和 Width 到 Height。然后将您的其他元素限制为该“持有人”视图:

class ViewController: UIViewController {
    
    let pgcHolder = UIView()
    let pgc = UIPageControl()
    let greenLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemYellow
        
        pgcHolder.translatesAutoresizingMaskIntoConstraints = false
        pgc.translatesAutoresizingMaskIntoConstraints = false
        greenLabel.translatesAutoresizingMaskIntoConstraints = false
    
        pgcHolder.addSubview(pgc)
        view.addSubview(pgcHolder)
        view.addSubview(greenLabel)
        
        let g = view.safeAreaLayoutGuide
    
        NSLayoutConstraint.activate([

            // center page control in its "holder" view
            pgc.centerXAnchor.constraint(equalTo: pgcHolder.centerXAnchor),pgc.centerYAnchor.constraint(equalTo: pgcHolder.centerYAnchor),// constrain holder view leading to view + 20,centerY
            pgcHolder.leadingAnchor.constraint(equalTo: g.leadingAnchor,pgcHolder.centerYAnchor.constraint(equalTo: g.centerYAnchor,// constrain holder view WIDTH to page control HEIGHT
            pgcHolder.widthAnchor.constraint(equalTo: pgc.heightAnchor),// constrain holder view HEIGHT to page control WIDTH
            pgcHolder.heightAnchor.constraint(equalTo: pgc.widthAnchor),// constrain greenLabel Leading to holder view trailing + 8 and centerY,safe area trailing -8
            greenLabel.leadingAnchor.constraint(equalTo: pgcHolder.trailingAnchor,greenLabel.centerYAnchor.constraint(equalTo: pgcHolder.centerYAnchor),])
        
        let angle = CGFloat.pi/2
        pgc.transform = CGAffineTransform(rotationAngle: angle)

        pgcHolder.backgroundColor = .systemRed
        pgc.backgroundColor = .systemBlue
        greenLabel.backgroundColor = .green
        
        pgc.numberOfPages = 8
        
        greenLabel.numberOfLines = 0
        greenLabel.text = "UIPageControl indicates the number of open pages in an application by displaying a dot for each open page. The dot that corresponds to the currently viewed page is highlighted. UIPageControl supports navigation by sending the delegate an event when a user taps to the right or to the left of the currently highlighted dot."

    }
    
}

现在我们有了我们想要的输出:

enter image description here