【问题标题】:Vertically rotated UIPageControl taking too much space垂直旋转的 UIPageControl 占用太多空间
【发布时间】:2021-04-23 15:48:23
【问题描述】:

我使用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)
 ])

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

启用宽度锚点:

【问题讨论】:

  • 尝试为此约束赋予负常数:noticesCollectionView.leadingAnchor.constraint(equalTo: noticesPagingIndicator.trailingAnchor)
  • 我可以这样做,但它不是一个黑客!我觉得仿射变换导致了这个问题。
  • 是的,因为当你变换时,它会受到限制。
  • 我们不能修复它以使边界也旋转吗?
  • 更改高度常数而不是宽度。

标签: ios swift autolayout uipagecontrol


【解决方案1】:

@DonMag 用故事板回答

第 1 步:

在 View Controller 中,拖动 UIVIew --> 将其命名为 (holderView)

第 2 步:

在 holderView 中拖动页面控件

第 4 步:

选择持有人View - 添加Center Y Constraint,Trailing Constraint with Super View

第 5 步:

选择页面 Control View - 添加 Center X , Center Y 约束

第 6 步:

从左侧面板的视图列表中,选择父视图和页面控制视图,添加 Equal With 和 Equal Height 约束

第 7 步:

现在选择 Equal Width 约束,并从左侧面板(约束属性)将 superView Width 更新为 SuperView Height,

高度约束也一样

你的约束应该是这样的

【讨论】:

    【解决方案2】:

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

    你得到这个输出:

    如您所见,页面控件尾锚的绿色标签前导约束显示页面控件 width 与没有旋转时的匹配。

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

    framew: 27.5 h: 217,但 boundsw: 217 h: 27.5

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

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

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

    【讨论】:

    • 你对iOS开发了解太多了! ??
    • 只有一个问题,我已经看到如果我有 20 个帖子,那么只有 4-5 个点显示在 4-5 个点之前和之后的一个小点表示还剩下更多帖子.在那种情况下,我真的需要设置高度约束吗?如果我们设置顶部和底部锚点会发生什么?那么页面控件会按照我所看到的方式运行吗?还是这只发生在 iOS 14 中?
    • @ParthTamane - 尝试一下。从一个标准的、非旋转的UIPageControl 开始,并注意 iOS 14 和更早版本之间的差异。在 14 之前,如果您的“点”多于可用宽度,您会怎么做?一旦你决定了你想如何处理它,然后看看当你旋转它时它是如何受到影响的。不过,这个问题与这个问题完全不同。
    • @ParthTamane - 记得将答案标记为已接受,以帮助可能遇到它的其他用户。
    • 是的,抱歉忘记了
    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2012-05-15
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2022-07-13
    • 2020-05-12
    • 1970-01-01
    相关资源
    最近更新 更多