Search code examples
iosswiftuikit

How to add a view to a free space?


In my application, the squares have to stand next to each other in a vacant space. The width and height of the square are determined by the stepper.

I tried this code, but I can't figure out how to determine the x and y position for a new square

@objc private func goButtonPressed() {
        let squareView: UIView = {
            let square = UIView()
            square.backgroundColor = .blue
            square.frame.size = CGSize(width: Int(stepperLabel.text!)!, height: Int(stepperLabel.text!)!)
            square.frame.origin = CGPoint(x: 0, y: 0)
            return square
        }()
        gameZone.addSubview(squareView)
    }

Screenshot


Solution

  • Here's a simple example written on the xcode playground. The idea is to increment to have to variables currentRow and currentColumn that are then converted to x and y by multiplying the square width.

    import PlaygroundSupport
    import UIKit
    import Foundation
    import PlaygroundSupport
    
    class ExampleViewController: UIViewController {
    
        let squaresByLine = 4
        var currentRow = 0
        var currentColumn = 0
    
        lazy var frameSize: CGSize = {
            let width = (view.frame.width / 4)
            return CGSize(width: width, height: width)
        }()
    
        private lazy var uiButton = {
            let btn = UIButton()
            btn.translatesAutoresizingMaskIntoConstraints = false
            btn.setTitle("Add", for: .normal)
            btn.setTitleColor(.black, for: .normal)
            btn.addAction(UIAction(handler: { [weak self] _ in
                self?.goButtonPressed()
            }), for: .touchUpInside)
            btn.backgroundColor = .green
            return btn
        }()
    
        private func goButtonPressed() {
            let x = CGFloat(currentColumn) * frameSize.width
            let y = CGFloat(currentRow) * frameSize.width
    
            debugPrint(x, y)
            let squareView: UIView = {
                let square = UIView()
                square.backgroundColor = .blue
                square.frame.size = frameSize
                square.frame.origin = CGPoint(x: x, y: y)
                return square
            }()
            view.addSubview(squareView)
    
            if currentColumn + 1 > squaresByLine {
                currentColumn = 0
                currentRow += 1
            } else {
                currentColumn += 1
            }
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(uiButton)
    
            NSLayoutConstraint.activate([
                uiButton.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                uiButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
                uiButton.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                uiButton.heightAnchor.constraint(equalToConstant: 80)
            ])
        }
    
    }
    
    let viewController = ExampleViewController()
    PlaygroundPage.current.liveView = UINavigationController(rootViewController: viewController)