मैं ग्रिड में प्रोग्रामेटिक रूप से कई बटन जोड़ने की कोशिश कर रहा हूं, जहां पंक्तियों की संख्या स्क्रीन आकार से अधिक है, इसलिए मैं उन्हें UIScrollView में चाहता हूं।

मेरा न्यूनतम कामकाजी उदाहरण निम्नलिखित है:

class ViewController: UIViewController {
    
    //center label and down a bit
    let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.width/2 - 100, y: 50, width: 200, height: 200))
    
    // start scroll view underneath label (why not y: 250?)
    let scrollView = UIScrollView(frame: CGRect(x: 0, y: 50, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
    
    override func viewDidLoad() {
        super.viewDidLoad()
                
        // add label to view
        self.view.addSubview(label)
        
        // add Scrollview
        self.view.addSubview(scrollView)
        // uncommenting the following also doesn't work
        //scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: 4000)
        
        // add buttons to scroll view in 5x21 grid
        var idx = 1
        for row in 0...20 {
            for col in 0...4 {
                let button = UIButton(frame: CGRect(x: col*50, y: row*50 + 200, width: 50, height: 50))
                button.backgroundColor = .gray
                button.setTitle("\(idx)", for: .normal)
                button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
                
                // add button to scroll view
                scrollView.addSubview(button)
                
                idx += 1
            }
        }
    }
    
    @objc func buttonAction(sender: UIButton!) {
        label.text = sender.title(for: .normal)
    }

}

दुर्भाग्य से स्क्रॉलिंग काम नहीं करता है। यहां तक ​​कि जब मैं स्पष्ट रूप से एक बड़ा लंबवत सामग्री आकार निर्धारित करता हूं (टिप्पणी की गई रेखा देखें) //scrollView.contentSize

मैं सोच रहा हूं कि तय किए गए बटनों के लिए x और y मान सेट करने से इसका कोई लेना-देना है या नहीं? लेकिन फिर मैं उन्हें ग्रिड में और कैसे संरेखित करूं?

तो, काम करने वाले स्क्रॉलव्यू प्राप्त करते समय मैं बटन संरेखण कैसे प्राप्त करूं?

1
Freya W 29 जुलाई 2021, 02:34

2 जवाब

सबसे बढ़िया उत्तर

आपको वास्तव में ऑटो-लेआउट का उपयोग करना चाहिए !!!

अब तक, स्क्रॉल व्यू में बटन (या कोई भी दृश्य) जोड़ने का सबसे आसान तरीका - ग्रिड लेआउट में जैसे आप पूछ रहे हैं - और क्या यह स्वचालित रूप से स्क्रॉलिंग क्षेत्र को स्टैक व्यू के साथ निर्धारित करता है।

यहाँ एक त्वरित उदाहरण है:

class ViewController: UIViewController {
    
    let label = UILabel()
    let scrollView = UIScrollView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // start with some text in the label
        label.text = "Tap a button"
        
        // center the text in the label
        label.textAlignment = .center
        
        // so we can see the frames
        label.backgroundColor = .yellow
        scrollView.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        
        // create a vertical stack view to hold the rows of buttons
        let verticalStackView = UIStackView()
        verticalStackView.axis = .vertical

        // we're going to use auto-layout
        label.translatesAutoresizingMaskIntoConstraints = false
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        verticalStackView.translatesAutoresizingMaskIntoConstraints = false

        // add label to view
        self.view.addSubview(label)
        
        // add Scrollview to view
        self.view.addSubview(scrollView)
        
        // add stack view to scrollView
        scrollView.addSubview(verticalStackView)

        // now let's create the buttons and add them
        var idx = 1
        
        for row in 0...20 {
            // create a "row" stack view
            let rowStack = UIStackView()
            // add it to the vertical stack view
            verticalStackView.addArrangedSubview(rowStack)
            
            for col in 0...4 {
                let button = UIButton()
                button.backgroundColor = .gray
                button.setTitle("\(idx)", for: .normal)
                button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
                
                // add button to row stack view
                rowStack.addArrangedSubview(button)
                
                // buttons should be 50x50
                NSLayoutConstraint.activate([
                    button.widthAnchor.constraint(equalToConstant: 50.0),
                    button.heightAnchor.constraint(equalToConstant: 50.0),
                ])
                
                idx += 1
            }
        }

        // finally, let's set our constraints
        
        // respect safe-area
        let safeG = view.safeAreaLayoutGuide

        NSLayoutConstraint.activate([
            
            // constrain label
            //  50-pts from top
            //  80% of the width
            //  centered horizontally
            label.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 50.0),
            label.widthAnchor.constraint(equalTo: safeG.widthAnchor, multiplier: 0.8),
            label.centerXAnchor.constraint(equalTo: safeG.centerXAnchor),
            
            // constrain scrollView
            //  50-pts from bottom of label
            //  Leading and Trailing to safe-area with 8-pts "padding"
            //  Bottom to safe-area with 8-pts "padding"
            scrollView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 50.0),
            scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 8.0),
            scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: -8.0),
            scrollView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: -8.0),
            
            // constrain vertical stack view to scrollView Content Layout Guide
            //  8-pts all around (so we have a little "padding")
            verticalStackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor, constant: 8.0),
            verticalStackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor, constant: 8.0),
            verticalStackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor, constant: -8.0),
            verticalStackView.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor, constant: -8.0),
            
        ])

    }
    
    @objc func buttonAction(sender: UIButton!) {
        label.text = sender.title(for: .normal)
    }
    
}

और यह परिणाम है:

enter image description here

फिर हम नीचे स्क्रॉल करेंगे और एक अलग बटन पर टैप करेंगे:

enter image description here

यदि आप बटनों के बीच रिक्ति चाहते हैं, तो आप viewDidLoad() के अंत में कुछ इस तरह जोड़ सकते हैं:

// suppose we want 8-pts spacing between the buttons?
verticalStackView.spacing = 8.0
verticalStackView.arrangedSubviews.forEach { v in
    if let stack = v as? UIStackView {
        stack.spacing = 8.0
    }
}

अब यह इस तरह दिखता है:

enter image description here

enter image description here

यदि आप चाहते हैं कि बटनों का ग्रिड क्षैतिज रूप से केंद्रित हो, या यदि आप रिक्ति (या बटन आकार) को फिट करने के लिए समायोजित करना चाहते हैं, तो ऐसा करने के कुछ अलग तरीके हैं... आपने अपने प्रश्न में अपने अंतिम लक्ष्य का वर्णन नहीं किया है, लेकिन यह एक अच्छा प्रारंभिक बिंदु होना चाहिए।

2
DonMag 29 जुलाई 2021, 16:32

मैंने संग्रह दृश्य के साथ वही काम किया जो स्क्रॉलव्यू का उप-वर्ग है और जो पंक्तियों/स्तंभों के संदर्भ में आपकी आवश्यकता के अनुरूप होगा।

इसके अतिरिक्त, स्क्रॉलव्यू के लिए स्पर्शों को प्रबंधित करने के लिए आपको स्क्रॉलव्यू के लिए UIScrollViewDelegate लागू करना होगा, विशेष रूप से स्पर्श करने और स्क्रॉल करने के बीच अंतर करने के लिए अन्यथा आप संभवतः अप्रत्याशित व्यवहार के साथ समाप्त हो जाएंगे।

0
christophe de poly 29 जुलाई 2021, 07:34