【问题标题】:UIView: how to update coordinates in XIB by programUIView:如何通过程序更新XIB中的坐标
【发布时间】:2021-12-14 17:28:49
【问题描述】:

我在一个名为 Container 的类中对 UIView 进行了子类化。 我想按程序给出容器框架的值。 为此,在我的 Container 类中,我有一个名为 customInit 的方法,如下所示:

public func customInit() {
        super.customInit()
        backgroundColor = .systemCyan
        frame.origin.x = 10
    }

(当然没那么简单,我只是想举个例子)。为了与 IB 交互,我在 Container 类中有:

override public func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        customInit()
    }

这样我在 customInit 中所做的更改就会反映在 IB 中。 this is what I see in IB

但是如果我在 IB 中选择视图,我会得到: what I see when container is selected

容器视图的位置很好,但是当我选择它时,IB 会显示另一个位置。 我了解我在 IB Inspector 中看到的值从未在 XIB 文件中更新 values in IB Inspector

如果 contentView 中包含多个容器视图,这可能会成为一个真正的问题(例如考虑键盘视图,其中每个键都由一个 Container 类表示)

所以我的问题是:是否可以更新 XIB 文件,或者至少让 IB 在选择视图时显示正确的位置?

【问题讨论】:

    标签: ios xcode interface-builder


    【解决方案1】:

    几乎可以肯定,问题在于您加载和初始化 XIB 视图的方式,但您没有显示该代码。

    对此有多种方法,包括扩展和“帮助程序”。

    这是一个非常简单的基本示例。 XIB 圆角并添加边框,并具有@IBOutlet 标签。它包括标签字符串、背景颜色和边框颜色的@IBDesignable 属性:

    在 IB 中是这样的:

    并且,在更改了几个 @IBInspectable 属性之后:

    基本XIBView.xib

    <?xml version="1.0" encoding="UTF-8"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
        <device id="retina3_5" orientation="portrait" appearance="light"/>
        <dependencies>
            <deployment identifier="iOS"/>
            <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
            <capability name="Safe area layout guides" minToolsVersion="9.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="BasicXIBView" customModule="QuickTest" customModuleProvider="target">
                <connections>
                    <outlet property="testLabel" destination="a7l-k8-xno" id="4zG-1N-QR0"/>
                </connections>
            </placeholder>
            <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
            <view contentMode="scaleToFill" id="iN0-l3-epB">
                <rect key="frame" x="0.0" y="0.0" width="320" height="229"/>
                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                <subviews>
                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="a7l-k8-xno">
                        <rect key="frame" x="139.5" y="104.5" width="41.5" height="20.5"/>
                        <color key="backgroundColor" red="0.97609727989999995" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                        <nil key="textColor"/>
                        <nil key="highlightedColor"/>
                    </label>
                </subviews>
                <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                <constraints>
                    <constraint firstItem="a7l-k8-xno" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="854-s5-92e"/>
                    <constraint firstItem="a7l-k8-xno" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="lpT-0r-6vc"/>
                </constraints>
                <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
                <point key="canvasLocation" x="-91.875" y="249.375"/>
            </view>
        </objects>
    </document>
    

    BasicXIBView.swift

    import UIKit
    
    @IBDesignable
    class BasicXIBView: UIView {
        
        @IBInspectable
        var str: String = "Test Label" {
            didSet {
                testLabel.text = str
            }
        }
        
        @IBInspectable
        var bkgColor: UIColor = .systemTeal {
            didSet {
                xibView.backgroundColor = bkgColor
            }
        }
        
        @IBInspectable
        var brdColor: UIColor = .systemBlue {
            didSet {
                xibView.layer.borderColor = brdColor.cgColor
            }
        }
        
        @IBOutlet var testLabel: UILabel!
        
        // reference to the view object loaded from the XIB / NIB
        var xibView: UIView!
        
        override func prepareForInterfaceBuilder() {
            super.prepareForInterfaceBuilder()
            commonInit()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            commonInit()
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            commonInit()
        }
        
        func commonInit() -> Void {
            if xibView == nil {
                guard let cv = Bundle(for: type(of: self)).loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)?.first as? UIView else {
                    return
                }
                self.insertSubview(cv, at: 0)
                cv.autoresizingMask = [.flexibleWidth, .flexibleHeight]
                cv.frame = bounds
                xibView = cv
            }
            
            // rounded corners, single pt border
            layer.borderWidth = 2
            layer.cornerRadius = 20
            layer.masksToBounds = true
            
            // IBInspectable properties
            testLabel.text = str
            xibView.backgroundColor = bkgColor
            layer.borderColor = brdColor.cgColor
        }
        
    }
    

    【讨论】:

    • 感谢您的回复,但我不明白更改变量 XibView 将如何更新 XIB 文件
    • 感谢您的回复,但我不明白更改变量 XibView 将如何更新我的应用程序中的 XIB 文件,我不使用 Xib 文件而是故事板(也许是更好地使用 XIB 文件?)我通过调用 sceneDelegate 来实例化视图控制器(它将包含名为 LoginContainer 的子类视图): let vc = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(identifier: “LoginViewController”)我不明白如何在我的子类中使用情节提要文件建立链接(不确定是否足够清楚)
    • @PatriceRapaport - 抱歉,您说:“所以我的问题是:是否可以更新 XIB 文件...” 所以我假设您是 使用 Xib 文件。您需要发布演示问题的完整课程(或至少是最小版本),以便我们帮助您编写代码。
    • 抱歉造成误解。所以我会再发一篇标题为:Is it possible to update the storyboard (我称它为 XIB 文件,但你是对的)
    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多