मैं एक स्क्रॉल व्यू रखना चाहता हूं जो मेरी सभी चीजों को लंबवत रूप से स्टैक व्यू में प्रदर्शित करता है।

  1. सबसे पहले, मैंने स्क्रॉल व्यू के भीतर contentView नाम का एक व्यू बनाया, जिसमें स्टैक व्यू होता है, जिसका अर्थ है कि अब मेरे पास view -> scrollView -> है। contentView -> stackView.
  2. मैंने सामग्री दृश्य के अग्रणी, अनुगामी, शीर्ष और निचले एंकर को स्क्रॉल दृश्य सामग्री लेआउट मार्गदर्शिका के उन बाधाओं के बराबर सेट किया है।
  3. मैंने सामग्री दृश्य की चौड़ाई को स्क्रॉल दृश्य फ़्रेम लेआउट मार्गदर्शिका की चौड़ाई के समान बनाया है।
  4. मैंने स्टैक व्यू के अग्रणी, अनुगामी, शीर्ष और निचले एंकर को सामग्री दृश्य के संबंधित एंकर के बराबर बनाया है।

enter image description here

यह स्क्रॉल नहीं करता है।

मैंने इस SO उत्तर का अनुसरण करने का प्रयास किया:

  1. मैंने Content Layout Guides से छुटकारा पाया और contentView की बाधाओं को सभी 4 पक्षों पर 0,0,0,0 होने के लिए लागू किया और इसे क्षैतिज और लंबवत रूप से स्क्रॉल दृश्य पर केंद्रित किया।
  2. आकार निरीक्षक में, नीचे बदलें और केंद्र Y प्राथमिकता को 250 पर संरेखित करें।
  3. स्टैक व्यू के निचले एंकर को view पर सेट करें (स्क्रॉल व्यू नहीं)।

enter image description here

यह केवल थोड़ा सा स्क्रॉल करता है, लेकिन पूरी तरह से नीचे स्क्रॉल नहीं करता है। अधिकांश दृश्य स्क्रीन के बाहर ही छिपा होता है।

मैंने contentView सभी को एक साथ निकालने की कोशिश की और अपने स्टैक व्यू को या तो सीधे स्क्रॉल व्यू या view पर पिन कर दिया, लेकिन किसी ने भी काम नहीं किया।

अंत में, मैंने इस सुपर हैकी-दिखने वाले समाधान की कोशिश की:

override func viewWillLayoutSubviews(){
    super.viewWillLayoutSubviews()
    scrollView.contentSize = CGSize(width: view.bounds.width, height: view.bounds.height+300)
}

लेकिन, यह स्टैक व्यू को लंबवत रूप से स्क्वीज़ करता है और सामग्री को पूरी तरह से प्रदर्शित नहीं करता है।

पी.एस. मैं स्टैक व्यू के लिए प्रोग्रामेटिक रूप से बाधाओं को जोड़ रहा हूं:

stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
0
Kevvv 16 अगस्त 2020, 00:05

2 जवाब

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

यहां एक उदाहरण दिया गया है जो काम करेगा - देखें कि क्या आप यह पता लगा सकते हैं कि आपने अलग तरीके से क्या किया होगा।

"सामग्री दृश्य" का उपयोग करने के बजाय हम कोड के माध्यम से सीधे स्क्रॉल दृश्य में स्टैक दृश्य जोड़ देंगे।

यहाँ स्टोरीबोर्ड लेआउट है:

enter image description here

स्टोरीबोर्ड का स्रोत यहां दिया गया है, ताकि आप इसकी सीधे जांच कर सकें:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="dVO-AO-rAX">
    <device id="retina3_5" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Kevvv View Controller-->
        <scene sceneID="e7x-2X-Pdg">
            <objects>
                <viewController id="dVO-AO-rAX" customClass="KevvvViewController" customModule="MiniScratch" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="ZMq-2S-yNo">
                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bEj-BB-5lU">
                                <rect key="frame" x="0.0" y="44" width="320" height="402"/>
                                <viewLayoutGuide key="contentLayoutGuide" id="VmC-Gj-CCr"/>
                                <viewLayoutGuide key="frameLayoutGuide" id="HBJ-Ua-m26"/>
                            </scrollView>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
                        <constraints>
                            <constraint firstItem="bEj-BB-5lU" firstAttribute="leading" secondItem="goZ-oS-cQl" secondAttribute="leading" id="Jwq-Tg-wRK"/>
                            <constraint firstItem="goZ-oS-cQl" firstAttribute="bottom" secondItem="bEj-BB-5lU" secondAttribute="bottom" constant="34" id="bHJ-DL-1xi"/>
                            <constraint firstItem="bEj-BB-5lU" firstAttribute="trailing" secondItem="goZ-oS-cQl" secondAttribute="trailing" id="gIL-OY-ENf"/>
                            <constraint firstItem="bEj-BB-5lU" firstAttribute="top" secondItem="goZ-oS-cQl" secondAttribute="top" constant="44" id="zAh-qk-82E"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="goZ-oS-cQl"/>
                    </view>
                    <connections>
                        <outlet property="scrollView" destination="bEj-BB-5lU" id="jYI-Wh-d6w"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="ieG-NN-t0K" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="136.875" y="105"/>
        </scene>
    </scenes>
</document>

और यहां उदाहरण कोड है जो स्क्रॉल दृश्य में एक स्टैक दृश्य जोड़ देगा, स्टैक दृश्य में 40 लेबल जोड़ देगा, और फिर स्टैक दृश्य को स्क्रॉल दृश्य में ठीक से सीमित कर देगा:

class KevvvViewController: UIViewController {

    @IBOutlet var scrollView: UIScrollView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 12
        
        stack.translatesAutoresizingMaskIntoConstraints = false
        
        scrollView.addSubview(stack)
        
        for i in 1...40 {
            let v = UILabel()
            v.backgroundColor = .yellow
            v.text = "Label \(i)"
            stack.addArrangedSubview(v)
        }

        NSLayoutConstraint.activate([
            stack.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
            stack.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
            stack.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
            stack.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
            
            stack.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor),
        ])
        
        // to make it easy to see the scroll view frame
        scrollView.backgroundColor = .cyan
    }
    
}

परिणाम, 17वें लेबल (iPhone 8) तक नीचे स्क्रॉल करने के बाद:

enter image description here

1
DonMag 17 अगस्त 2020, 18:25

ऐसा लगता है कि आपको केवल एक UIScrollView और एक UIStackView की आवश्यकता है:

enter image description here

UIScrollView और UIStackView दोनों ने ऊपर, नीचे, अग्रणी और अनुगामी बाधाओं को अपने-अपने पर्यवेक्षण के लिए निर्धारित किया है। UIStackView की चौड़ाई और Safe Area चौड़ाई के बीच एकमात्र अंतर अंतिम बाधा है। (यह इस बात पर निर्भर करता है कि आप UIStackView की कितनी चौड़ाई चाहते हैं)

आपको यह सुनिश्चित करने के लिए UIStackView के Distribution को Equal Spacing जैसी किसी चीज़ पर सेट करने की आवश्यकता हो सकती है कि यह हमेशा इसकी सामग्री के आधार पर फैलता है।

साथ ही, UIStackView में कुछ जोड़ें ताकि ऑटो लेआउट शिकायत करना बंद कर दे। (इंटरफ़ेस बिल्डर पर लाल बाधाओं से बचें)

इसे मार दें।

0
gcharita 16 अगस्त 2020, 00:44