Vertically rotated UIPageControl taking too much space

冷暖自知 提交于 2021-02-11 12:21:46

问题


I used CGAffineTransform to rotate a horizontal UIPageControl vertical. But when I added it besides my collection view it's taking too much width. And when I add a width anchor on it, the UIPageControl disappears.

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)
 ])

When I look at the UIView hierarchy, I see a lot of padding along the UIPageControl

With the width anchor enabled:


回答1:


Get to know the Debug View Hierarchy tool. It can help you figure out most layout issues.

When you transform a view, that doesn't change its bounds and thus doesn't change its constraint relationships to other UI elements.

With this code (8 pages, so 8 dots):

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."
        
    }
    
}

You get this output:

As you've seen, the Green Label Leading constraint to the page control Trailing Anchor shows the page control width matches what it would be without the rotation.

If you inspect the views with Debug View Hierarchy, you'll see the page control looks like this:

The frame is w: 27.5 h: 217 but the bounds is w: 217 h: 27.5.

To fix this, you need to embed the page control in a "holder" view, constrain the holder view's Height to the page control's Width and Width to Height. Then constrain your other elements to that "holder" view:

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, constant: 20.0),
            pgcHolder.centerYAnchor.constraint(equalTo: g.centerYAnchor, constant: 0.0),
            
            // 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, constant: 8.0),
            greenLabel.centerYAnchor.constraint(equalTo: pgcHolder.centerYAnchor),
            greenLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -8.0),
            
        ])
        
        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."

    }
    
}

Now we have our desired output:



来源:https://stackoverflow.com/questions/65789901/vertically-rotated-uipagecontrol-taking-too-much-space

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!