使用 UIPickerView 选定行使用数组数据更新 UIButton 标题

Posted

技术标签:

【中文标题】使用 UIPickerView 选定行使用数组数据更新 UIButton 标题【英文标题】:Update UIButton title with array data using UIPickerView selected row 【发布时间】:2019-08-20 16:26:34 【问题描述】:

这个问题之前已经讨论过,但我就是不明白。

(Set Title of UIButton from Selected Row of UIPickerView in swift) (Set Title of UIButton from Selected Row of UIPickerView)

我有三个按钮来显示 UIPickerView。

button1.addTarget(self, action: #selector(showPicker), for: .touchUpInside)
button2.addTarget(self, action: #selector(showPicker), for: .touchUpInside)
button3.addTarget(self, action: #selector(showPicker), for: .touchUpInside)

根据点击的按钮,选择器数据(modelData)和标签被更新。

@objc func showFilterPicker(sender: UIButton)
    if sender.tag == 238 
        modelData = someStringArray1
        filterPickerView.reloadAllComponents()
        filterPickerView.tag = 2238
     else if sender.tag == 239 
        modelData = someStringArray2
        filterPickerView.reloadAllComponents()
        filterPickerView.tag = 2239
     else if sender.tag == 240 
        modelData = someStringArray3
        filterPickerView.reloadAllComponents()
        filterPickerView.tag = 2240
    

更新按钮标题

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
    if filterPickerView.tag == 2238 
        button1.setTitle(modelData[row], for: .normal)
     else if filterPickerView.tag == 2239 
        button2.setTitle(modelData[row], for: .normal)
     else if filterPickerView.tag == 2240 
        button3.setTitle(modelData[row], for: .normal)
    

但是,这不起作用。

任何建议或更详细的链接答案示例都会有所帮助,谢谢。

--

查看层次结构

override func viewDidLoad() 
    view.addSubview(outerView)
    outerView.addSubview(scrollView)
    scrollView.addSubview(containerView)
    containerView.addSubview(button1)
    containerView.addSubview(button2)
    containerView.addSubview(button3)
    view.addSubview(pickerContainerView)
    pickerContainerView.addSubview(filterPickerView)

【问题讨论】:

你是什么意思“这不起作用”didSelectRow 没有被调用?它被调用了,但是你得到了错误的字符串?它被调用了,你得到了正确的字符串,但是按钮没有在视觉上更新? didSelectRow 被调用,但在该方法完成后,包含选择器和按钮的视图消失 您发布的任何内容都没有表明您的按钮或选择器视图在视图层次结构中的位置,并且您的代码中的任何内容都不会导致您所描述的内容。由于您是 Stack Overflow 的新手,欢迎您,但请使用 tour 并查看 How to Ask。 选择器和按钮位于主视图的不同子视图中。这有什么不同吗? Set Title of UIButton from Selected Row of UIPickerView的可能重复 【参考方案1】:

这是一个完整的功能示例。没有 IBOutlets 或 IBActions,所以只需为这个类分配一个新的视图控制器:

//
//  DeanViewController.swift
//  TestProj
//
//  Created by Don Mag on 8/20/19.
//

import UIKit

class DeanViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource 

    let button1: UIButton = 
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .red
        b.setTitle("Button 1", for: .normal)
        return b
    ()

    let button2: UIButton = 
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .red
        b.setTitle("Button 2", for: .normal)
        return b
    ()

    let button3: UIButton = 
        let b = UIButton()
        b.translatesAutoresizingMaskIntoConstraints = false
        b.backgroundColor = .red
        b.setTitle("Button 3", for: .normal)
        return b
    ()


    let filterPickerView: UIPickerView = 
        let v = UIPickerView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    ()

    let buttonStackView: UIStackView = 
        let v = UIStackView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.axis = .vertical
        v.spacing = 8
        return v
    ()

    let containerView: UIView = 
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        return v
    ()

    let pickerContainerView: UIView = 
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .green
        return v
    ()

    let scrollView: UIScrollView = 
        let v = UIScrollView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .blue
        return v
    ()

    let data1 = ["One", "Two", "Three"]
    let data2 = ["This", "is", "a", "Test"]
    let data3 = ["A", "B", "C", "D", "E"]

    var modelData: [String] = [String]()

    override func viewDidLoad() 
        super.viewDidLoad()

        // add the 3 buttons to the stack view
        buttonStackView.addArrangedSubview(button1)
        buttonStackView.addArrangedSubview(button2)
        buttonStackView.addArrangedSubview(button3)

        // add the stack view to the container view
        containerView.addSubview(buttonStackView)

        // add the container view to the scroll view
        scrollView.addSubview(containerView)

        // add the picker view to its container view
        pickerContainerView.addSubview(filterPickerView)

        // add the picker container view to the scroll view
        scrollView.addSubview(pickerContainerView)

        // add the scroll view to the view
        view.addSubview(scrollView)

        // setup the constraints
        NSLayoutConstraint.activate([

            buttonStackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 20.0),
            buttonStackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -20.0),
            buttonStackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 20.0),
            buttonStackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -20.0),

            filterPickerView.topAnchor.constraint(equalTo: pickerContainerView.topAnchor, constant: 20.0),
            filterPickerView.bottomAnchor.constraint(equalTo: pickerContainerView.bottomAnchor, constant: -20.0),
            filterPickerView.leadingAnchor.constraint(equalTo: pickerContainerView.leadingAnchor, constant: 20.0),
            filterPickerView.trailingAnchor.constraint(equalTo: pickerContainerView.trailingAnchor, constant: -20.0),

            containerView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 20.0),
            containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 20.0),
            containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0.0),

            pickerContainerView.topAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 20.0),
            pickerContainerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 20.0),
            pickerContainerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0.0),

            pickerContainerView.bottomAnchor.constraint(greaterThanOrEqualTo: scrollView.bottomAnchor, constant: 20.0),
            pickerContainerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -40.0),

            scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),

            ])

        modelData = data1
        filterPickerView.tag = 1

        filterPickerView.dataSource = self
        filterPickerView.delegate = self

        button1.addTarget(self, action: #selector(btnTap(_:)), for: .touchUpInside)
        button2.addTarget(self, action: #selector(btnTap(_:)), for: .touchUpInside)
        button3.addTarget(self, action: #selector(btnTap(_:)), for: .touchUpInside)

    

    @objc func btnTap(_ sender: UIButton) -> Void 

        if sender == button1 
            modelData = data1
            filterPickerView.tag = 1
         else if sender == button2 
            modelData = data2
            filterPickerView.tag = 2
         else 
            modelData = data3
            filterPickerView.tag = 3
        

        filterPickerView.reloadAllComponents()

    

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) 
        var btn: UIButton?
        if pickerView.tag == 1 
            btn = button1
         else if pickerView.tag == 2 
            btn = button2
         else 
            btn = button3
        
        btn?.setTitle(modelData[row], for: .normal)
    

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? 
        return modelData[row]
    

    func numberOfComponents(in pickerView: UIPickerView) -> Int 
        return 1
    

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int 
        return modelData.count
    


结果:

蓝色是滚动视图的背景色; 绿色是选择器容器视图的背景色 青色是按钮容器视图的背景颜色(按钮也嵌入在堆栈视图中)

点击每个按钮会更改选择器中的数据,选择选择器中的一行会更改关联按钮的标题。

【讨论】:

感谢您的回答。我已经比较了代码,它现在适用于我的情况。虽然我找不到确切的区别,但这对我来说是一个非常明确的解决方案

以上是关于使用 UIPickerView 选定行使用数组数据更新 UIButton 标题的主要内容,如果未能解决你的问题,请参考以下文章

获取 UIPickerView 中每个组件的选定行

UIPickerView从中间的选定行开始

如何使用 UIPickerView 的选定值作为通知的时间间隔?

如何更改 UIPickerView 中选定行的颜色

如何更改 UIPickerView 中选定行的颜色

显示带有选定行的 UIPickerView