UIScrollView 中元素显示不正确

问题描述 投票:0回答:1

我使用屏幕上的滚动条。同时,在SE上显示屏幕时没有问题,在大屏幕上显示时,两个元素之间会出现较大的间隙。 如何改变这个问题呢? 我改变了约束,但没有结果

import UIKit

class PlayInfoViewController: UIViewController {
    private let mainScrollView: UIScrollView = {
        let sv = UIScrollView()
        sv.backgroundColor = UIColor(named: "backgroundColor")
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()
    
    private let contentView: UIView = {
        let v = UIView()
        v.backgroundColor = UIColor(named: "backgroundColor")
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    private let horisontalStackViews: [UIStackView] = {
        var stackViews: [UIStackView] = []
        let textsForMainLabel = [
            "Draw a grid with three rows and three columns, creating nine squares in total.",
            "Players take turns placing their marker (X or O) in an empty square. To make a move, a player selects a number corresponding to the square where they want to place their marker.",
            "Player X starts by choosing a square (e.g., square 5). Player O follows by choosing an empty square (e.g., square 1). Continue alternating turns until the game ends.",
            "The first player to align three of their markers horizontally, vertically, or diagonally wins. Examples of Winning Combinations: Horizontal: Squares 1, 2, 3 or 4, 5, 6 or 7, 8, 9 Vertical: Squares 1, 4, 7 or 2, 5, 8 or 3, 6, 9 Diagonal: Squares 1, 5, 9 or 3, 5, 7"
        ]
        
        var number = 1
        for text in textsForMainLabel {
            let hStackView = UIStackView(
                arrangedSubviews: [
                    RoundView(
                        frame: CGRect.zero,
                        numberOfPosition: number
                    ),
                    RectangleView(
                        frame: CGRect.zero,
                        textForMainLabel: text
                    )
                ],
                axis: .horizontal,
                spacing: 20,
                alignment: .top)
            
            stackViews.append(hStackView)
            number += 1
        }
        
        return stackViews
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor(named: "backgroundColor")
       
        setupViews()
        setConstraints()
    }
    
    private func setupViews() {
        view.addSubview(mainScrollView)
        mainScrollView.addSubview(contentView)
        
        view.addSubview(horisontalStackViews[0])
        view.addSubview(horisontalStackViews[1])
        view.addSubview(horisontalStackViews[2])
        view.addSubview(horisontalStackViews[3])
        
        horisontalStackViews[0].translatesAutoresizingMaskIntoConstraints = false
        horisontalStackViews[1].translatesAutoresizingMaskIntoConstraints = false
        horisontalStackViews[2].translatesAutoresizingMaskIntoConstraints = false
        horisontalStackViews[3].translatesAutoresizingMaskIntoConstraints = false
        
        let hConst = contentView.heightAnchor.constraint(equalTo: mainScrollView.heightAnchor)
        hConst.isActive = true
        hConst.priority = UILayoutPriority(500)
    }
}

extension PlayInfoViewController {
    private func setConstraints() {
        NSLayoutConstraint.activate([
            mainScrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            mainScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 42),
            mainScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            mainScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
       
            contentView.leadingAnchor.constraint(equalTo: mainScrollView.leadingAnchor),
            contentView.topAnchor.constraint(equalTo: mainScrollView.topAnchor),
            contentView.trailingAnchor.constraint(equalTo: mainScrollView.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: mainScrollView.bottomAnchor),
            contentView.widthAnchor.constraint(equalTo: mainScrollView.widthAnchor),
            //            contentView.heightAnchor.constraint(equalTo: mainScrollView.heightAnchor, multiplier: 2),
  
            horisontalStackViews[0].leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 21),
            horisontalStackViews[0].topAnchor.constraint(equalTo: contentView.topAnchor),
            horisontalStackViews[0].trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -21),
            //            horisontalStackViews[0].widthAnchor.constraint(equalTo: contentView.widthAnchor),
            //            horisontalStackViews[0].heightAnchor.constraint(equalToConstant: 75)
     
            horisontalStackViews[1].leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 21),
            horisontalStackViews[1].topAnchor.constraint(equalTo: horisontalStackViews[0].bottomAnchor, constant: 10),
            horisontalStackViews[1].trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -21),
            //            horisontalStackViews[1].widthAnchor.constraint(equalTo: contentView.widthAnchor),
            //            horisontalStackViews[1].heightAnchor.constraint(equalToConstant: 192)

            horisontalStackViews[2].leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 21),
            horisontalStackViews[2].topAnchor.constraint(equalTo: horisontalStackViews[1].bottomAnchor, constant: 10),
            horisontalStackViews[2].trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -21),
            //            horisontalStackViews[2].widthAnchor.constraint(equalTo: contentView.widthAnchor),
            //            horisontalStackViews[2].heightAnchor.constraint(equalToConstant: 171)

            horisontalStackViews[3].leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 21),
            horisontalStackViews[3].topAnchor.constraint(equalTo: horisontalStackViews[2].bottomAnchor, constant: 10),
            horisontalStackViews[3].trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -21),
            horisontalStackViews[3].bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            //            horisontalStackViews[3].widthAnchor.constraint(equalTo: contentView.widthAnchor),
            //            horisontalStackViews[3].heightAnchor.constraint(equalToConstant: 255)
        ])
    }
}

我更改约束和 hConst。没有结果

 horisontalStackViews[3].bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
let hConst = contentView.heightAnchor.constraint(equalTo: mainScrollView.heightAnchor)
        hConst.isActive = true
        hConst.priority = UILayoutPriority(500)

class RoundView: UIView {
    var numberOfPosition: Int
    
    lazy var numberLabel: UILabel = {
        let label = UILabel()
        label.text = "Some text"
        label.font = UIFont.systemFont(ofSize: 20, weight: .regular)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    required init(frame: CGRect, numberOfPosition: Int) {
        self.numberOfPosition = numberOfPosition
        super.init(frame: frame)
        
        layer.cornerRadius = 22.5
        translatesAutoresizingMaskIntoConstraints = false
        
        numberLabel.text = String(numberOfPosition)
        
        setupView()
        setConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        backgroundColor = #colorLiteral(red: 0.8375778794, green: 0.7538908124, blue: 0.96424371, alpha: 1)
        
        addSubview(numberLabel)
    }
}

extension RoundView {
    private func setConstraints() {
        NSLayoutConstraint.activate([
            numberLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 18),
            numberLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -18),
            numberLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            numberLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
        ])
    }
}

class RectangleView: UIView {
    var textForMainLabel: String
    
    lazy var mainLabel: UILabel = {
        let label = UILabel()
        label.text = "Some text"
        label.font = UIFont.systemFont(ofSize: 18, weight: .regular)
        label.numberOfLines = 0
        label.minimumScaleFactor = 0.5
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    required init(frame: CGRect, textForMainLabel: String) {
        self.textForMainLabel = textForMainLabel
        super.init(frame: frame)
        
        layer.cornerRadius = 30
        translatesAutoresizingMaskIntoConstraints = false
        
        mainLabel.text = textForMainLabel
        
        setupView()
        setConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        backgroundColor = #colorLiteral(red: 0.8718322515, green: 0.8867664933, blue: 0.9465543628, alpha: 1)
        
        addSubview(mainLabel)
    }
}

extension RectangleView {
    private func setConstraints() {
        NSLayoutConstraint.activate([
            mainLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 24),
            mainLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -24),
            mainLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            mainLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
        ])
    }
}

很好 在此输入图片描述

这是错误的

在此输入图片描述

swift uiscrollview uikit
1个回答
0
投票

我们不要限制水平堆栈视图“行”,而是将它们添加到垂直堆栈视图中。

为了避免大屏幕上第一和第二“行”之间的“间隙”,我们在垂直堆栈视图或“内容”视图上设置高度约束。在小屏幕上——比如 SE——我们可以滚动。在较大的屏幕上,我们在底部留出一点空间,同时保持“行间距”一致。

看起来像这样:

Result


圆景

class RoundView: UIView {
    var numberOfPosition: Int
    
    lazy var numberLabel: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.text = "0"
        label.font = UIFont.systemFont(ofSize: 20, weight: .regular)
        label.translatesAutoresizingMaskIntoConstraints = false
        
        // make sure the label frame cannot compress
        label.setContentCompressionResistancePriority(.required, for: .horizontal)
        label.setContentCompressionResistancePriority(.required, for: .vertical)
        
        return label
    }()
    
    required init(frame: CGRect, numberOfPosition: Int) {
        self.numberOfPosition = numberOfPosition
        super.init(frame: frame)
        
        translatesAutoresizingMaskIntoConstraints = false
        
        numberLabel.text = String(numberOfPosition)
        
        setupView()
        setConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        backgroundColor = #colorLiteral(red: 0.8375778794, green: 0.7538908124, blue: 0.96424371, alpha: 1)
        
        addSubview(numberLabel)
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        // set the cornerRadius here to make sure it matches the view size
        layer.cornerRadius = min(bounds.height, bounds.width) * 0.5
    }

}

extension RoundView {
    private func setConstraints() {
        NSLayoutConstraint.activate([
            numberLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 18),
            numberLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -18),
            numberLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            numberLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12),
            
            // let's keep this view at a 1:1 aspect ratio
            self.widthAnchor.constraint(equalTo: self.heightAnchor),
        ])
    }
}

矩形视图

class RectangleView: UIView {
    var textForMainLabel: String
    
    lazy var mainLabel: UILabel = {
        let label = UILabel()
        label.text = "Some text"
        label.font = UIFont.systemFont(ofSize: 18, weight: .regular)
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    required init(frame: CGRect, textForMainLabel: String) {
        self.textForMainLabel = textForMainLabel
        super.init(frame: frame)
        
        layer.cornerRadius = 30
        translatesAutoresizingMaskIntoConstraints = false
        
        mainLabel.text = textForMainLabel
        
        setupView()
        setConstraints()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupView() {
        backgroundColor = #colorLiteral(red: 0.8718322515, green: 0.8867664933, blue: 0.9465543628, alpha: 1)
        
        addSubview(mainLabel)
    }
}

extension RectangleView {
    private func setConstraints() {
        NSLayoutConstraint.activate([
            mainLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 24),
            mainLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -24),
            mainLabel.topAnchor.constraint(equalTo: topAnchor, constant: 12),
            mainLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12)
        ])
    }
}

PlayInfoViewController

class PlayInfoViewController: UIViewController {
    private let mainScrollView: UIScrollView = {
        let sv = UIScrollView()
        sv.backgroundColor = UIColor(named: "backgroundColor")
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()
    
    private let contentView: UIView = {
        let v = UIView()
        v.backgroundColor = UIColor(named: "backgroundColor")
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()
    
    // vertical stack view to hold the "rows" of horizontal stack views
    private let vertStackView: UIStackView = {
        let sv = UIStackView()
        sv.axis = .vertical
        sv.spacing = 10
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()
    
    private let horisontalStackViews: [UIStackView] = {
        var stackViews: [UIStackView] = []
        let textsForMainLabel = [
            "Draw a grid with three rows and three columns, creating nine squares in total.",
            "Players take turns placing their marker (X or O) in an empty square. To make a move, a player selects a number corresponding to the square where they want to place their marker.",
            "Player X starts by choosing a square (e.g., square 5). Player O follows by choosing an empty square (e.g., square 1). Continue alternating turns until the game ends.",
            "The first player to align three of their markers horizontally, vertically, or diagonally wins. Examples of Winning Combinations: Horizontal: Squares 1, 2, 3 or 4, 5, 6 or 7, 8, 9 Vertical: Squares 1, 4, 7 or 2, 5, 8 or 3, 6, 9 Diagonal: Squares 1, 5, 9 or 3, 5, 7"
        ]
        
        var number = 1
        
        for text in textsForMainLabel {
            let hStackView = UIStackView()
            hStackView.axis = .horizontal
            hStackView.spacing = 20
            hStackView.alignment = .top
            
            let roundView = RoundView (
                frame: CGRect.zero,
                numberOfPosition: number
            )
            let rectView = RectangleView (
                frame: CGRect.zero,
                textForMainLabel: text
            )
            
            hStackView.addArrangedSubview(roundView)
            hStackView.addArrangedSubview(rectView)
            
            stackViews.append(hStackView)
            number += 1
        }
        
        return stackViews
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor(named: "backgroundColor")
        
        setupViews()
        setConstraints()
    }
    
    private func setupViews() {
        view.addSubview(mainScrollView)
        mainScrollView.addSubview(contentView)
        contentView.addSubview(vertStackView)

        for v in horisontalStackViews {
            vertStackView.addArrangedSubview(v)
        }
    }
}

extension PlayInfoViewController {
    private func setConstraints() {
        
        let g = view.safeAreaLayoutGuide
        let cg = mainScrollView.contentLayoutGuide
        let fg = mainScrollView.frameLayoutGuide
        
        NSLayoutConstraint.activate([
            mainScrollView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            mainScrollView.topAnchor.constraint(equalTo: g.topAnchor, constant: 42),
            mainScrollView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            mainScrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
            
            contentView.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
            contentView.topAnchor.constraint(equalTo: cg.topAnchor),
            contentView.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
            contentView.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
            contentView.widthAnchor.constraint(equalTo: fg.widthAnchor),
            
            // do NOT set contentView.heightAnchor
            
            vertStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 21),
            vertStackView.topAnchor.constraint(equalTo: contentView.topAnchor),
            vertStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -21),
            vertStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
        ])
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.