【问题标题】:Save button states when we move segmented control当我们移动分段控件时保存按钮状态
【发布时间】:2022-01-14 10:21:58
【问题描述】:

例如,我们有分段控件和按钮数组。如果我们在一个片段中选择一个按钮 - 按钮需要保存状态,然后我们移动到另一个片段并选择另一个按钮。但是如果我们回到上一个按钮 - 它应该在我们之前选择的位置。 也就是说,每个段都必须存储按钮的状态。 如何做得更好?

struct SegmentsModel {
      let title: String
      var answered: Bool
      var buttonIndex: Int? = nil
}

@objc private func buttonsTapped(_ sender: UIButton) {
        let _ = buttons.map({$0.isSelected = false})
         sender.isSelected = true
        guard let index = buttons.firstIndex(of: sender) else { return }

        switch index {
        case 0:
            selectedSegment(segmentedControl, buttonSelected: true, indexButton: 0)
        case 1:
            selectedSegment(segmentedControl, buttonSelected: true, indexButton: 1)
        case 2:
            selectedSegment(segmentedControl, buttonSelected: true, indexButton: 2)
        case 3:
            selectedSegment(segmentedControl, buttonSelected: true, indexButton: 3)
        default:
            break
        }
}

     @objc private func selectedSegment(_ sender: UISegmentedControl, 
                                        buttonSelected: Bool, indexButton: Int) {
        let currentIndex = sender.selectedSegmentIndex
        
        if buttonSelected == true {
            buttons[indexButton].isSelected = true
        } else {
            let _ = buttons.map({$0.isSelected = false})
        }
        
        switch currentIndex {
        case 0:
            arrayOfSegments[0].answered = buttonSelected
            arrayOfSegments[0].buttonIndex = indexButton
        case 1:
            arrayOfSegments[1].answered = buttonSelected
            arrayOfSegments[1].buttonIndex = indexButton
        case 2:
            arrayOfSegments[2].answered = buttonSelected
            arrayOfSegments[2].buttonIndex = indexButton
        default:
            break
        }
    }
    

【问题讨论】:

  • 有很多方法可以做到这一点,这更像是一个软件设计问题。例如,您可以创建一个数组来存储每个段的活动按钮的状态。您可以使用字典,该字典使用段的唯一内容作为键,并将所选按钮作为其值。您甚至可以使用结构来实现这一点。所以选择是你的,或者问题需要更多地关注你尝试了什么,什么没有奏效。我唯一可以确定的是,在您的段操作处理程序中,您需要根据之前存储的内容重新加载按钮状态。
  • 你能用更新状态写一个简短的例子吗?)我有一个模型,当我点击一个片段中的一个按钮时,我将按钮的索引保存到这个模型,并保存属性“ buttonClicked”,布尔状态。
  • 我建议您将您尝试过的代码添加到您的问题中,并解释哪个部分没有按预期工作。这样我(或其他人)可以帮助我们提出最好的建议。
  • 我添加了我的示例
  • 所以你有 3 个段和 4 个按钮。对于每个段,您只能选择 1 个按钮?例如,在第 32 段中,我选择了按钮 1。在第 33 段中,我选择了按钮 2。如果我回到第 32 段,它应该以红色显示按钮 1。这是你想要达到的目标吗?

标签: arrays swift button uisegmentedcontrol


【解决方案1】:

正如我在我的 cmets 中提到的,有很多方法可以实现您想要的。我将与您分享一个想法。

我看到您尝试将所有按钮存储在一个数组中,并且必须不断循环它们以确定之前选择了哪个按钮。既然你想让代码有更简单的逻辑,那我给你一个不同的思路。

实现您想要的一种方法是使用标签。每个 UIView 对象都有一个标签,默认设置为 0。

使用故事板,我将按钮的标签设置为 100、101、102、103,这也可以通过编程方式完成。

你可以选择任何你喜欢的整数,但重要的是给它们一些唯一的数字,这样当你尝试按标签获取视图时,你只会得到你想要的视图。

所以设置完标签后,我在代码中更新了这个。

struct SegmentsModel {
    let title: String
    var answered = false
    var buttonIndex: Int? = nil
    {
        // Auto-update the value of answered when value of buttonIndex changes
        didSet
        {
            answered = buttonIndex != nil
        }
    }
}

我在这里没有做任何重大更新。我只添加了一个属性观察器,所以当按钮索引被设置时,被回答的变量也是自动设置的,所以你不必为此做更多的事情

接下来,下面是管理段和按钮的所有逻辑。我将 UIViewController 与 StoryBoard 一起使用,因此您可能需要忽略某些内容。 所有重要的代码都有 cmets,所以你可以跟着。

class ViewController: UIViewController {
    
    // I will store the results in this array
    var storedResults: [SegmentsModel] = []
    
    // Segment control outlet
    @IBOutlet weak var segmentControl: UISegmentedControl!
    
    // Array of buttons
    @IBOutlet var buttons: [UIButton]!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Loop over all segments
        for index in 0 ..< segmentControl.numberOfSegments
        {
            // Initialize and store default results values in storedResults array
            if let segmentTile = segmentControl.titleForSegment(at: index)
            {
                storedResults.append(SegmentsModel(title: segmentTile))
            }
        }
    }
    
    // Segment action
    @IBAction func selectedSegment(_ sender: UISegmentedControl)
    {
        // Update the UI of buttons
        reloadButtons()
    }
    
    
    @IBAction func buttonTapped(_ sender: UIButton)
    {
        // Reset your buttons
        let _ = buttons.map({$0.isSelected = false})
        
        // Set the current button to selected
        sender.isSelected = true
        
        // Get the current result so we can update it
        var currentResult = storedResults[segmentControl.selectedSegmentIndex]
        
        // Update the current segments selected button index using tag
        currentResult.buttonIndex = sender.tag
        
        // Put the result back into the array as structs as value types
        storedResults[segmentControl.selectedSegmentIndex] = currentResult
    }
    
    // Reload button data
    private func reloadButtons()
    {
        // Reset your buttons
        let _ = buttons.map({$0.isSelected = false})
        
        let currentResult = storedResults[segmentControl.selectedSegmentIndex]
        
        // Check if current index has a selected button and if it does retrieve it
        // with a tag
        if let selectedButtonIndex = currentResult.buttonIndex,
           let selectedButton = view.viewWithTag(selectedButtonIndex) as? UIButton
        {
            // Show the selected button in the UI
            selectedButton.isSelected = true
        }
    }
}

达到的最终结果可以是seen in this youtube video,我相信这就是您想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多