顶部菜单栏中的单个按钮下划线

Posted

技术标签:

【中文标题】顶部菜单栏中的单个按钮下划线【英文标题】:Underline Single Button from Top menu bar 【发布时间】:2020-04-17 19:15:45 【问题描述】:
    如图所示MyTopBar 我在滚动视图中有 5 个 uibuttons。我将它用作导航/顶部栏 我只想在 5 个按钮中的选定按钮上实现下划线效果。图片Target 我看到了一些库,但没有像我预期的那样工作 我将刷新相同的视图,所以这不是很有用 能否告诉我一种实现这种下划线效果的简单方法?

【问题讨论】:

如果您找到了一个“库”,它可以满足您的大部分需求,请尝试编辑该代码......或者至少挖掘它以查看正在执行的操作。如果只是不想“更改视图控制器”,则应该很容易找到并更改按钮点击时发生的操作。 这不是我的意思,对不起,我也编辑了这个问题,我确实尝试了库,它不仅仅是改变 VC,但它并没有像我想要的那样工作 您是否在 Storyboard 中设计您的 MyTopBar?还是通过代码创建它(添加按钮等)? 我正在使用 StoryBoard,因为我附上了图片。 【参考方案1】:

有多种方法可以做到这一点。这是一种方法...

将按钮放在水平堆栈视图中 添加UIView 作为您的“下划线视图”

对于您的“下划线视图”:

将高度限制设置为 4 设置顶部约束等于堆栈视图的底部 设置 widthAnchor 等于第一个按钮 widthAnchor,常量 8(宽 4 点) 将 centerXAnchor 设置为等于第一个按钮 centerXAnchor

将宽度和中心锚点连接到自定义类中的@IBOutlets。

点击按钮时:

停用宽度和 centerX 约束 将它们设置为点击按钮 重新激活它们 根据需要设置动画位置

以下是示例实现的代码:

protocol TopBarButtonTapProtocol 
    func didSelect(_ sender: UIButton)


class MyTopBar: UIView 

    var delegate: TopBarButtonTapProtocol?

    @IBOutlet var theStack: UIStackView!
    @IBOutlet var uView: UIView!

    @IBOutlet var uWidth: NSLayoutConstraint!
    @IBOutlet var uCenter: NSLayoutConstraint!

    override func didMoveToWindow() 
        super.didMoveToWindow()

        let btns = theStack.arrangedSubviews

        btns.forEach  v in
            guard let btn = v as? UIButton else 
                fatalError("Stack view must contain buttons only!")
            
            btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
        

    

    @objc func didTap(_ sender: UIButton) -> Void 
        uCenter.isActive = false
        uWidth.isActive = false
        uCenter = uView.centerXAnchor.constraint(equalTo: sender.centerXAnchor)
        uWidth = uView.widthAnchor.constraint(equalTo: sender.widthAnchor, constant: 8)
        uCenter.isActive = true
        uWidth.isActive = true
        UIView.animate(withDuration: 0.3) 
            self.layoutIfNeeded()
        
        delegate?.didSelect(sender)
    



class TestMyTopBarViewController: UIViewController, TopBarButtonTapProtocol 

    @IBOutlet var myTopBar: MyTopBar!

    override func viewDidLoad() 
        super.viewDidLoad()
        myTopBar.delegate = self
    

    func didSelect(_ sender: UIButton) 
        print("Top Bar button selected:", sender.currentTitle)
    


这里是示例故事板的来源:

<?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="abg-zX-CIL">
    <device id="retina4_7" 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>
        <!--Test My Top Bar View Controller-->
        <scene sceneID="Jte-e1-dR6">
            <objects>
                <viewController id="abg-zX-CIL" customClass="TestMyTopBarViewController" customModule="MiniScratch" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="TsC-q0-s74">
                        <rect key="frame" x="0.0" y="0.0"  />
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kx6-5a-S6X" customClass="MyTopBar" customModule="MiniScratch" customModuleProvider="target">
                                <rect key="frame" x="0.0" y="0.0"  />
                                <subviews>
                                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BXS-ke-LLN">
                                        <rect key="frame" x="0.0" y="0.0"  />
                                        <subviews>
                                            <stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Gtj-bJ-9xt">
                                                <rect key="frame" x="16" y="8"  />
                                                <subviews>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ljU-s4-4DJ">
                                                        <rect key="frame" x="0.0" y="0.0"  />
                                                        <state key="normal" title="FOR YOU">
                                                            <color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                        </state>
                                                    </button>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="242-wz-PkM">
                                                        <rect key="frame" x="81" y="0.0"  />
                                                        <state key="normal" title="TRENDING">
                                                            <color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                        </state>
                                                    </button>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c15-qj-lxv">
                                                        <rect key="frame" x="172" y="0.0"  />
                                                        <state key="normal" title="NEW">
                                                            <color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                        </state>
                                                    </button>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5DP-bs-qBc">
                                                        <rect key="frame" x="222" y="0.0"  />
                                                        <state key="normal" title="FEATURED">
                                                            <color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                        </state>
                                                    </button>
                                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZfK-40-1VN">
                                                        <rect key="frame" x="313" y="0.0"  />
                                                        <state key="normal" title="BOOKMARKS">
                                                            <color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                        </state>
                                                    </button>
                                                </subviews>
                                            </stackView>
                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="974-mZ-VM1">
                                                <rect key="frame" x="12" y="38"  />
                                                <color key="backgroundColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstAttribute="height" constant="4" id="rvK-8e-XTq"/>
                                                </constraints>
                                            </view>
                                        </subviews>
                                        <constraints>
                                            <constraint firstItem="Gtj-bJ-9xt" firstAttribute="trailing" secondItem="Zfb-Kx-C2I" secondAttribute="trailing" constant="16" id="4nw-75-kgv"/>
                                            <constraint firstItem="974-mZ-VM1" firstAttribute="centerX" secondItem="ljU-s4-4DJ" secondAttribute="centerX" id="9Ig-gt-a62"/>
                                            <constraint firstItem="Gtj-bJ-9xt" firstAttribute="leading" secondItem="Zfb-Kx-C2I" secondAttribute="leading" constant="16" id="EGu-UL-6tD"/>
                                            <constraint firstItem="Gtj-bJ-9xt" firstAttribute="bottom" secondItem="Zfb-Kx-C2I" secondAttribute="bottom" id="Fby-qZ-GyD"/>
                                            <constraint firstItem="974-mZ-VM1" firstAttribute="width" secondItem="ljU-s4-4DJ" secondAttribute="width" constant="8" id="GNh-W8-umn"/>
                                            <constraint firstItem="974-mZ-VM1" firstAttribute="top" secondItem="Gtj-bJ-9xt" secondAttribute="bottom" id="QeJ-UW-lPh"/>
                                            <constraint firstItem="Gtj-bJ-9xt" firstAttribute="top" secondItem="Zfb-Kx-C2I" secondAttribute="top" constant="8" id="gXv-a7-43N"/>
                                            <constraint firstItem="x1k-em-xS5" firstAttribute="bottom" secondItem="Gtj-bJ-9xt" secondAttribute="bottom" constant="8" id="yQ5-dH-18H"/>
                                        </constraints>
                                        <viewLayoutGuide key="contentLayoutGuide" id="Zfb-Kx-C2I"/>
                                        <viewLayoutGuide key="frameLayoutGuide" id="x1k-em-xS5"/>
                                    </scrollView>
                                </subviews>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <constraints>
                                    <constraint firstAttribute="trailing" secondItem="BXS-ke-LLN" secondAttribute="trailing" id="1Qh-mv-QIl"/>
                                    <constraint firstItem="BXS-ke-LLN" firstAttribute="top" secondItem="kx6-5a-S6X" secondAttribute="top" id="XBR-Uf-huR"/>
                                    <constraint firstItem="BXS-ke-LLN" firstAttribute="leading" secondItem="kx6-5a-S6X" secondAttribute="leading" id="YyI-HM-ve8"/>
                                    <constraint firstAttribute="bottom" secondItem="BXS-ke-LLN" secondAttribute="bottom" id="ioI-y3-Lmd"/>
                                </constraints>
                                <connections>
                                    <outlet property="theStack" destination="Gtj-bJ-9xt" id="5XU-eX-2NB"/>
                                    <outlet property="uCenter" destination="9Ig-gt-a62" id="TxH-Bf-Hy0"/>
                                    <outlet property="uView" destination="974-mZ-VM1" id="BZ0-ne-Fcb"/>
                                    <outlet property="uWidth" destination="GNh-W8-umn" id="aFq-4f-sQu"/>
                                </connections>
                            </view>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
                        <constraints>
                            <constraint firstItem="kx6-5a-S6X" firstAttribute="top" secondItem="u6w-w1-8iK" secondAttribute="top" id="KhJ-Id-pdJ"/>
                            <constraint firstItem="kx6-5a-S6X" firstAttribute="trailing" secondItem="u6w-w1-8iK" secondAttribute="trailing" id="R2z-YZ-Vkl"/>
                            <constraint firstItem="kx6-5a-S6X" firstAttribute="leading" secondItem="u6w-w1-8iK" secondAttribute="leading" id="ifV-RN-a6g"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="u6w-w1-8iK"/>
                    </view>
                    <navigationItem key="navigationItem" id="cpA-Qb-gmu">
                        <barButtonItem key="rightBarButtonItem" systemItem="add" id="mAr-W2-GXa">
                            <connections>
                                <action selector="addBtnPressed:" destination="abg-zX-CIL" id="OIu-lZ-j2s"/>
                            </connections>
                        </barButtonItem>
                    </navigationItem>
                    <connections>
                        <outlet property="myTopBar" destination="kx6-5a-S6X" id="Ssi-YG-3F2"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="wfE-oG-abp" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="1703" y="1657"/>
        </scene>
    </scenes>
</document>

这是它在运行时的样子,按钮向左滚动,“精选”按钮被选中:

【讨论】:

这比我现在实施的要好得多。但是有一个问题,我如何确保在任何给定时间,一个按钮必须处于活动状态。即下划线? 如果你在 Storyboard 中设计它(根据我的例子),第一个按钮将是“活动的”(下划线)。

以上是关于顶部菜单栏中的单个按钮下划线的主要内容,如果未能解决你的问题,请参考以下文章

Java的API文档能不能放到桌面上的菜单栏中啊,那样方便查找

如何更改菜单栏中的 Xamarin 后退按钮?

向下滚动后无法访问导航栏中的菜单按钮

从管理栏中删除菜单项(在顶部)

菜单栏中的登录/注销字段不合适且不起作用(Wordpress)

MFC中如何在菜单栏中添加按钮