简体   繁体   中英

need constraints for y position, need constraints for x position

I'm trying to create a reusable textfield like view that shows the description above the textfield when there is text in the textfield. When I try the following constraints, I don't have any issue until I embed the stack view into a view. I need the view because I want to apply the styles to that view, and I want the description and the textfield/view content to be displayed enclosed by the styled view.

This is my xib:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="FormView" customModule="InToOut" customModuleProvider="target"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="iN0-l3-epB">
            <rect key="frame" x="0.0" y="0.0" width="394" height="233"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6MT-Kf-be6">
                    <rect key="frame" x="0.0" y="0.0" width="394" height="233"/>
                    <subviews>
                        <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="eXL-HZ-eBt">
                            <rect key="frame" x="0.0" y="0.0" width="394" height="233"/>
                            <subviews>
                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2m5-ox-32Z">
                                    <rect key="frame" x="0.0" y="0.0" width="394" height="20.5"/>
                                    <color key="backgroundColor" systemColor="systemYellowColor"/>
                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                    <nil key="textColor"/>
                                    <nil key="highlightedColor"/>
                                </label>
                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="pvU-v7-kCR">
                                    <rect key="frame" x="0.0" y="20.5" width="394" height="212.5"/>
                                    <color key="backgroundColor" systemColor="systemOrangeColor"/>
                                    <constraints>
                                        <constraint firstAttribute="height" constant="212.5" id="Ra7-Fa-LuZ"/>
                                    </constraints>
                                </view>
                            </subviews>
                            <color key="backgroundColor" systemColor="systemGreenColor"/>
                        </stackView>
                    </subviews>
                    <color key="backgroundColor" systemColor="systemYellowColor"/>
                    <constraints>
                        <constraint firstItem="eXL-HZ-eBt" firstAttribute="top" secondItem="6MT-Kf-be6" secondAttribute="top" id="DrL-7d-1nd"/>
                        <constraint firstItem="eXL-HZ-eBt" firstAttribute="leading" secondItem="6MT-Kf-be6" secondAttribute="leading" id="Zra-Wo-zbi"/>
                        <constraint firstAttribute="bottom" secondItem="eXL-HZ-eBt" secondAttribute="bottom" id="rDg-kX-Cyw"/>
                        <constraint firstAttribute="trailing" secondItem="eXL-HZ-eBt" secondAttribute="trailing" id="uVW-rD-C8t"/>
                    </constraints>
                </view>
            </subviews>
            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
            <point key="canvasLocation" x="-21.739130434782609" y="344.53125"/>
        </view>
    </objects>
    <resources>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
        <systemColor name="systemGreenColor">
            <color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
        <systemColor name="systemOrangeColor">
            <color red="1" green="0.58431372549019611" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
        <systemColor name="systemYellowColor">
            <color red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
    </resources>
</document>

Here is my xib's class:



import UIKit

class FormView: NibView {

}

Here is my definition of NibView


import UIKit

/// NibView is provided to reuse nib initialization code.
/// **Steps to use:**
/// 1. Create a swift file for your custom view, make your custom view a sub class of NibView like so
/// ```
/// class MyCustomView: NibView {
/// ```
/// 2.  Create a corresponding  xib file for your custom View: `⌘ n  →  View  →  Next`
/// 3.  Open your xib, select the `file owner` under `PlaceHolders` in the second most left tab,
/// then once selected, click on the identity inspector, the 4th column in the right most tab, and type
/// the name of your custom view, it should autopopulate as you type.  You do not need the view to be
/// a subclass of `MyCustomView` in the identity inspector, only the file Owner.
@IBDesignable class NibView: UIView {
    var view: UIView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }

    func xibSetup() {
        backgroundColor = .clear
        guard let nibView = loadNib() else {
            assertionFailure("Could not load the nib")
            return
        }
        view = nibView
        inject(view: view)
    }
}

extension UIView {

    /// Inserts a subview and constrains it to fill this view (the superview) by default.
    ///  Using string formats supports older OS.  This has an early exit if the
    /// view is already injected.  This also clears the subViews before injecting.
    /// - Parameters:
    ///   - view: The view you are injecting
    func inject(view: UIView) {
        guard !subviews.contains(view) else { return }
        if subviews.count > 0 { subviews.forEach { $0.removeFromSuperview() }}
        view.frame = bounds
        addSubview(view)
        view.translatesAutoresizingMaskIntoConstraints = false
        [
            topAnchor.constraint(equalTo: view.topAnchor),
            leftAnchor.constraint(equalTo: view.leftAnchor),
            rightAnchor.constraint(equalTo: view.rightAnchor),
            bottomAnchor.constraint(equalTo: view.bottomAnchor)
        ].forEach {
            $0.isActive = true
        }
    }

    func loadNib() -> UIView? {
        type(of: self).description().components(separatedBy: ".").last.flatMap {
            UINib(nibName: $0, bundle: Bundle(for: type(of: self)))
                .instantiate(withOwner: self, options: nil).first as? UIView
        }
    }
}

Looks like you have provided enough constraints for your UIStackView that has id="eXL-HZ-eBt" . There are four constraints - top , leading , bottom & trailing with this id.

However the new UIView (with id="6MT-Kf-be6" ) that wraps the stack view does not have any constraints specified. Although it's size can be driven by stack view size (which is driven by it's contents/subviews), you still need to provide it top & leading constraints so Autolayout can compute where it's position should be on the screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM