移动分段控件时保存按钮状态
Save button states when we move segmented control
例如,我们有分段控件和按钮数组。如果我们 select 一个段中的按钮之一 - 按钮需要保存状态,然后我们移动到另一个段并选择另一个按钮。但如果我们回到上一个按钮——它应该在我们之前选择的位置。
也就是说,每个段都必须存储按钮的状态。
如何做得更好?
struct SegmentsModel {
let title: String
var answered: Bool
var buttonIndex: Int? = nil
}
@objc private func buttonsTapped(_ sender: UIButton) {
let _ = buttons.map({[=10=].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({[=10=].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
}
}
正如我在评论中提到的,有很多方法可以实现您想要的。我将与您分享一个想法。
我看到您试图将所有按钮存储在一个数组中,并且不得不不断遍历它们以找出之前选择了哪个按钮。既然你希望代码逻辑更简单,我给你一个不同的思路。
实现您想要的目标的一种方法是使用标签。每个 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 一起使用,因此您可能需要忽略某些内容。
所有重要的代码都有注释,因此您可以跟进。
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({[=11=].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({[=11=].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,我相信这就是你想要的。
例如,我们有分段控件和按钮数组。如果我们 select 一个段中的按钮之一 - 按钮需要保存状态,然后我们移动到另一个段并选择另一个按钮。但如果我们回到上一个按钮——它应该在我们之前选择的位置。 也就是说,每个段都必须存储按钮的状态。 如何做得更好?
struct SegmentsModel {
let title: String
var answered: Bool
var buttonIndex: Int? = nil
}
@objc private func buttonsTapped(_ sender: UIButton) {
let _ = buttons.map({[=10=].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({[=10=].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
}
}
正如我在评论中提到的,有很多方法可以实现您想要的。我将与您分享一个想法。
我看到您试图将所有按钮存储在一个数组中,并且不得不不断遍历它们以找出之前选择了哪个按钮。既然你希望代码逻辑更简单,我给你一个不同的思路。
实现您想要的目标的一种方法是使用标签。每个 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 一起使用,因此您可能需要忽略某些内容。 所有重要的代码都有注释,因此您可以跟进。
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({[=11=].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({[=11=].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,我相信这就是你想要的。