stackView swift中uibutton问题的自动布局/宽度

Posted

技术标签:

【中文标题】stackView swift中uibutton问题的自动布局/宽度【英文标题】:Auto-layout/width of uibutton problem in stackView swift 【发布时间】:2021-02-04 14:05:42 【问题描述】:

我有一个 UIScrollView,在其中我有一个 UIStackView,我将其附加到几个 UIButtons 中,现在当我附加一个 UIButton 时,大小会发生变化:\ 它的大小也不相同 + 文本正在剪切:\我试图找到问题但找不到它:(。 这是我的代码:(必须说我使用故事板进行 uiscrollview+uistackview 的自动布局)

这是自动布局的图片:Link https://imgur.com/a/DcIUBfA

这是它的外观图片:

import UIKit

class ByHashtags: UITableViewCell 
    
    @IBOutlet var hashTagOptionsStackView: UIStackView!
    @IBOutlet var selectedHashtagsStackView: UIStackView!
    
    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
        
        self.preservesSuperviewLayoutMargins = false
        self.separatorInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        self.layoutMargins = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        
        insertOptionButtons()
        
    
    
    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)
        
        // Configure the view for the selected state
    
    
    fileprivate func insertOptionButtons() 
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
        button.setTitle("#sport", for: .normal)
        button.titleLabel?.font =  UIFont(name: "Helvetica", size: 12)

        button.addTarget(self, action: #selector(insertIntoStackView(_:)), for: .touchUpInside)
        
        button.backgroundColor = #colorLiteral(red: 0.8394575715, green: 0.9233128428, blue: 0.9912871718, alpha: 1)
        button.setTitleColor(#colorLiteral(red: 0.3784077764, green: 0.6974633336, blue: 0.9678211808, alpha: 1), for: .normal)
        button.layer.cornerRadius = 12
        button.translatesAutoresizingMaskIntoConstraints = false
        
      
        let button2 = UIButton()
        button2.setTitle("#healing", for: .normal)
        button2.titleLabel?.font =  UIFont(name: "Helvetica", size: 12)

        button2.addTarget(self, action: #selector(insertIntoStackView(_:)), for: .touchUpInside)
        button2.backgroundColor = #colorLiteral(red: 0.8394575715, green: 0.9233128428, blue: 0.9912871718, alpha: 1)
        button2.setTitleColor(#colorLiteral(red: 0.3784077764, green: 0.6974633336, blue: 0.9678211808, alpha: 1), for: .normal)
        button2.layer.cornerRadius = 12

        button2.translatesAutoresizingMaskIntoConstraints = false
        
        let button3 = UIButton()
        button3.setTitle("#morningstory", for: .normal)
        button3.titleLabel?.font =  UIFont(name: "Helvetica", size: 12)

        
        button3.addTarget(self, action: #selector(insertIntoStackView(_:)), for: .touchUpInside)

        
        button3.backgroundColor = #colorLiteral(red: 0.8394575715, green: 0.9233128428, blue: 0.9912871718, alpha: 1)
        button3.setTitleColor(#colorLiteral(red: 0.3784077764, green: 0.6974633336, blue: 0.9678211808, alpha: 1), for: .normal)
        button3.layer.cornerRadius = 12

        button3.translatesAutoresizingMaskIntoConstraints = false
        
        hashTagOptionsStackView.alignment = .fill
        hashTagOptionsStackView.distribution = .fillEqually
        hashTagOptionsStackView.spacing = 10.0
        
        
        hashTagOptionsStackView.addArrangedSubview(button)
        hashTagOptionsStackView.addArrangedSubview(button2)
        hashTagOptionsStackView.addArrangedSubview(button3)
        
    
    
    
    @objc func insertIntoStackView(_ sender: UIButton) 

        selectedHashtagsStackView.addArrangedSubview(sender)
    
    

【问题讨论】:

您需要在单元原型中显示您在堆栈视图上设置的约束。 我在这里看不到任何 UIScrollView。将stackview添加到scrollview,并设置边缘约束到scrollview内容指南。当您将按钮添加到stackview时,只需将按钮的内容拥抱优先级设置为required(或1000)。 @DonMag 我用约束编辑了帖子 @AviavSabag - 图片链接无效。 @DonMag 现在可以工作了,由于某种原因无效.. :| 【参考方案1】:

几个问题...

这一行:

button.frame = CGRect(x: 0, y: 0, width: 100, height: 50)

什么都不做,因为堆栈视图中的按钮使用自动布局。

如果您希望所有按钮的宽度为 100,请设置堆栈视图的 .distribution = .fill 并为每个按钮设置宽度约束:

button.widthAnchor.constraint(equalToConstant: 100).isActive = true

对于您的滚动视图,请确保将堆栈视图限制为滚动视图的Content Layout Guide,并将堆栈视图的高度限制为等于滚动视图的Frame Layout Guide 高度。

这是一个 xib,应该给你(接近)你想要的东西:

请注意,IB 不喜欢不完整的滚动视图布局,因此给每个堆栈视图一个内部内容大小“占位符”:

这是 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="retina6_1" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="153" id="pPM-g6-WWs" customClass="ByHashtags" customModule="PanZoom" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0"  />
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pPM-g6-WWs" id="OXE-su-1dl">
                <rect key="frame" x="0.0" y="0.0"  />
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="By Hashtags" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0iV-vu-7Zu">
                        <rect key="frame" x="16" y="10"  />
                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
                        <nil key="textColor"/>
                        <nil key="highlightedColor"/>
                    </label>
                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JTS-SC-VrS" userLabel="ListOfHashTags">
                        <rect key="frame" x="16" y="40.5"  />
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" placeholderIntrinsicWidth="200" placeholderIntrinsicHeight="30" translatesAutoresizingMaskIntoConstraints="NO" id="a09-ub-dWX">
                                <rect key="frame" x="0.0" y="0.0"  />
                            </stackView>
                        </subviews>
                        <color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="a09-ub-dWX" firstAttribute="top" secondItem="nAx-F0-JiF" secondAttribute="top" id="1cC-PE-OeC"/>
                            <constraint firstItem="a09-ub-dWX" firstAttribute="height" secondItem="EAz-Mr-cfG" secondAttribute="height" id="Cmq-3F-kpO"/>
                            <constraint firstItem="a09-ub-dWX" firstAttribute="trailing" secondItem="nAx-F0-JiF" secondAttribute="trailing" id="DGV-I8-KLb"/>
                            <constraint firstAttribute="height" constant="40" id="YmK-dU-qj1"/>
                            <constraint firstItem="a09-ub-dWX" firstAttribute="bottom" secondItem="nAx-F0-JiF" secondAttribute="bottom" id="ieC-6z-MMz"/>
                            <constraint firstItem="a09-ub-dWX" firstAttribute="leading" secondItem="nAx-F0-JiF" secondAttribute="leading" id="t6l-u1-8P9"/>
                        </constraints>
                        <viewLayoutGuide key="contentLayoutGuide" id="nAx-F0-JiF"/>
                        <viewLayoutGuide key="frameLayoutGuide" id="EAz-Mr-cfG"/>
                    </scrollView>
                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Trending:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WCQ-ix-GRZ">
                        <rect key="frame" x="16" y="100.5"  />
                        <fontDescription key="fontDescription" type="system" weight="light" pointSize="17"/>
                        <nil key="textColor"/>
                        <nil key="highlightedColor"/>
                    </label>
                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="u2n-IY-Fdc" userLabel="HashTagsOption">
                        <rect key="frame" x="103" y="90.5"  />
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" placeholderIntrinsicWidth="200" placeholderIntrinsicHeight="30" translatesAutoresizingMaskIntoConstraints="NO" id="YxX-2S-tyP">
                                <rect key="frame" x="0.0" y="0.0"  />
                            </stackView>
                        </subviews>
                        <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="YxX-2S-tyP" firstAttribute="leading" secondItem="Uns-Dw-jnK" secondAttribute="leading" id="4ZO-sx-0DL"/>
                            <constraint firstAttribute="height" constant="40" id="Aj5-oj-mtC"/>
                            <constraint firstItem="YxX-2S-tyP" firstAttribute="top" secondItem="Uns-Dw-jnK" secondAttribute="top" id="DE6-FD-VA3"/>
                            <constraint firstItem="YxX-2S-tyP" firstAttribute="trailing" secondItem="Uns-Dw-jnK" secondAttribute="trailing" id="Gha-rq-BV7"/>
                            <constraint firstItem="YxX-2S-tyP" firstAttribute="bottom" secondItem="Uns-Dw-jnK" secondAttribute="bottom" id="KXv-PA-vML"/>
                            <constraint firstItem="YxX-2S-tyP" firstAttribute="height" secondItem="6Sx-2o-tss" secondAttribute="height" id="Riu-eV-99K"/>
                        </constraints>
                        <viewLayoutGuide key="contentLayoutGuide" id="Uns-Dw-jnK"/>
                        <viewLayoutGuide key="frameLayoutGuide" id="6Sx-2o-tss"/>
                    </scrollView>
                </subviews>
                <constraints>
                    <constraint firstItem="u2n-IY-Fdc" firstAttribute="top" secondItem="JTS-SC-VrS" secondAttribute="bottom" constant="10" id="3r3-Ai-onp"/>
                    <constraint firstItem="JTS-SC-VrS" firstAttribute="leading" secondItem="OXE-su-1dl" secondAttribute="leading" constant="16" id="880-ZB-ECh"/>
                    <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="u2n-IY-Fdc" secondAttribute="bottom" constant="10" id="Kwo-76-H59"/>
                    <constraint firstAttribute="trailing" secondItem="u2n-IY-Fdc" secondAttribute="trailing" constant="16" id="PbP-Ha-Y2v"/>
                    <constraint firstItem="0iV-vu-7Zu" firstAttribute="leading" secondItem="OXE-su-1dl" secondAttribute="leading" constant="16" id="Pt2-nX-hef"/>
                    <constraint firstItem="WCQ-ix-GRZ" firstAttribute="leading" secondItem="OXE-su-1dl" secondAttribute="leading" constant="16" id="SKF-CH-ixU"/>
                    <constraint firstAttribute="trailing" secondItem="JTS-SC-VrS" secondAttribute="trailing" constant="16" id="T0G-Am-A6U"/>
                    <constraint firstItem="u2n-IY-Fdc" firstAttribute="leading" secondItem="WCQ-ix-GRZ" secondAttribute="trailing" constant="16" id="YCK-v4-CBa"/>
                    <constraint firstItem="WCQ-ix-GRZ" firstAttribute="centerY" secondItem="u2n-IY-Fdc" secondAttribute="centerY" id="da9-N8-o27"/>
                    <constraint firstItem="JTS-SC-VrS" firstAttribute="top" secondItem="0iV-vu-7Zu" secondAttribute="bottom" constant="10" id="f5p-e1-IaC"/>
                    <constraint firstItem="0iV-vu-7Zu" firstAttribute="top" secondItem="OXE-su-1dl" secondAttribute="top" constant="10" id="tOy-83-JJx"/>
                </constraints>
            </tableViewCellContentView>
            <connections>
                <outlet property="hashTagOptionsStackView" destination="YxX-2S-tyP" id="y5U-sR-n3E"/>
                <outlet property="selectedHashtagsStackView" destination="a09-ub-dWX" id="HV5-3W-Hvo"/>
            </connections>
            <point key="canvasLocation" x="152.17391304347828" y="84.040178571428569"/>
        </tableViewCell>
    </objects>
</document>

这是示例控制器和单元代码:

class HashtagsTableViewController: UITableViewController 
    
    override func viewDidLoad() 
        super.viewDidLoad()
        // register the nib for reuse
        let nib = UINib(nibName: "ByHashtags", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "bhNib")
    
    
    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 1
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let c = tableView.dequeueReusableCell(withIdentifier: "bhNib", for: indexPath) as! ByHashtags
        return c
    
    


class ByHashtags: UITableViewCell 
    
    @IBOutlet var hashTagOptionsStackView: UIStackView!
    @IBOutlet var selectedHashtagsStackView: UIStackView!
    
    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
        
        self.preservesSuperviewLayoutMargins = false
        self.separatorInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        self.layoutMargins = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
        
        insertOptionButtons()
    
    
    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)
    
    
    fileprivate func insertOptionButtons() 
        
        let btns: [String] = [
            "sport", "healing", "morningstory", "another", "something", "six", "seven", "eight"
        ]
        
        btns.forEach  str in

            let button = UIButton(type: .custom)
            button.setTitle("#" + str, for: .normal)
            button.titleLabel?.font =  UIFont(name: "Helvetica", size: 12)
            
            button.addTarget(self, action: #selector(insertIntoStackView(_:)), for: .touchUpInside)
            
            button.backgroundColor = #colorLiteral(red: 0.8394575715, green: 0.9233128428, blue: 0.9912871718, alpha: 1)
            button.setTitleColor(#colorLiteral(red: 0.3784077764, green: 0.6974633336, blue: 0.9678211808, alpha: 1), for: .normal)
            button.layer.cornerRadius = 12
            button.translatesAutoresizingMaskIntoConstraints = false

            button.widthAnchor.constraint(equalToConstant: 100).isActive = true
            
            hashTagOptionsStackView.addArrangedSubview(button)
        

        hashTagOptionsStackView.alignment = .fill
        hashTagOptionsStackView.distribution = .fill
        hashTagOptionsStackView.spacing = 10.0
        
        selectedHashtagsStackView.alignment = .fill
        selectedHashtagsStackView.distribution = .fill
        selectedHashtagsStackView.spacing = 10.0

    
    
    @objc func insertIntoStackView(_ sender: UIButton) 
        selectedHashtagsStackView.addArrangedSubview(sender)
    
    

点击第一个按钮后的结果(我为滚动视图设置了背景颜色以便于查看框架):

【讨论】:

哇,非常感谢你,伙计,你帮了我很多(再一次)真的很感谢。我真的需要在自动布局方面从我身边工作,但你对 swift 还是有点陌生​​ :)

以上是关于stackView swift中uibutton问题的自动布局/宽度的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3 - 自定义 UIButton 半径删除约束?

如何在swift中使用for循环将按钮添加到stackview?

Swift - 如何在水平 StackView 中设置可变数量按钮之间的间距?

将自定义参数传递给 uibutton #selector swift 3

如果没有内容,如何从 stackview 中删除 UIButton

stackView 中的 StackView 不能通过 swift 使用它的间距