2017-10-14 93 views
1

我有我使用的代码从该柱子类5段segmentedControl:UISegmentedControl取消选择未在代码识别虽然是在视觉上

How to deselect a segment in Segmented control button permanently till its clicked again

,以允许取消所述控制器当第二次触摸所选段。

这可以直观地工作,但是当试图分配一个UserDefault时,它只是被识别为被触摸了两次的段。

我无法弄清楚我可以添加到子类代码或viewController代码,使其工作。

任何帮助,将不胜感激。

子类代码:

class mySegmentedControl: UISegmentedControl { 
    @IBInspectable var allowReselection: Bool = true 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
     let previousSelectedSegmentIndex = self.selectedSegmentIndex 
     super.touchesEnded(touches, with: event) 
     if allowReselection && previousSelectedSegmentIndex == self.selectedSegmentIndex { 
      if let touch = touches.first { 
       let touchLocation = touch.location(in: self) 

       if bounds.contains(touchLocation) { 
        self.sendActions(for: .valueChanged) 
        self.selectedSegmentIndex = UISegmentedControlNoSegment 
       } 
      } 
     } 
    } 

}

视图控制器CODE:

所有的
@IBOutlet weak var METDome_L: UISegmentedControl! 
let key_METDome_L = "METDome_L" 
var METD_L: String! 

@IBAction func METDome_Lselect(_ sender: Any) { 
    if METDome_L.selectedSegmentIndex == 0{ 
     METD_L = "1" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
    else if METDome_L.selectedSegmentIndex == 1{ 
     METD_L = "2" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
    else if METDome_L.selectedSegmentIndex == 2{ 
     METD_L = "3" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
    else if METDome_L.selectedSegmentIndex == 3{ 
     METD_L = "4" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
    else if METDome_L.selectedSegmentIndex == 4{ 
     METD_L = "5" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
    else{ 
     METD_L = "NONE" 
     UserDefaults.standard.set(METD_L, forKey: key_METDome_L) 
    } 
} 
+0

没有关系,但你可以用一条线替换'METDome_Lselect' **的**整个代码:'UserDefaults.standard.set( “\(sender.selectedSegmentIndex + 1)”,forKey:key_METDome_L)' 。无论如何,最后的'else'永远不会被执行。顺便说一下,这不是Javascript或PHP。变量名称应该是* camelCased *而不是* snake_cased *。 – vadian

+0

谢谢@vadian!我知道必须有一种方法来缩短代码,但从来没有想过按照你说的方式去做,所以这真的很有帮助。 然而,其他部分是我真正需要工作的代码。我也尝试过'如果METDome_L.selectedSegmentIndex == UISegmentedControlNoSegment',但我想这也永远不会被执行。 关于变量名的说明,大部分我已经使用_camelCased_我只是使用下划线来分隔变量的各个部分,以便更容易识别,因为我对编码相当陌生,而且我很容易因数量而丢失数据的代码。 –

+0

我怀疑'IBAction'是以编程方式取消选择控件时触发的。你可以移动这条线将'NONE'写入子类 – vadian

回答

0

首先,如果你继承你必须使用该类型来获取增强的功能控制。

@IBOutlet weak var METDome_L: MySegmentedControl! // class names start with a capital letter 

添加属性selectionKeyUserDefaults保存状态UISegmentedControlNoSegment(如Int)当控制被取消选择。如果属性为空(必须在使用该子类的视图控制器中设置),则引发fatal error

class MySegmentedControl: UISegmentedControl { 
    @IBInspectable var allowReselection: Bool = true 

    var selectionKey = "" 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
     let previousSelectedSegmentIndex = self.selectedSegmentIndex 
     super.touchesEnded(touches, with: event) 
     if allowReselection && previousSelectedSegmentIndex == self.selectedSegmentIndex { 
      if let touch = touches.first { 
       let touchLocation = touch.location(in: self) 

       if bounds.contains(touchLocation) { 
        self.sendActions(for: .valueChanged) 
        self.selectedSegmentIndex = UISegmentedControlNoSegment 
        guard !selectionKey.isEmpty else { fatalError("selectionKey must not be empty") 
        UserDefaults.standard.set(UISegmentedControlNoSegment, forKey: selectionKey) 
       } 
      } 
     } 
    } 
} 

在您的视图控制器设置属性selectionKeyviewDidLoad到自定义按键和控制的选中状态保存到UserDefaultsIBAction。不要任何数学。第一个段是索引为0的段0。习惯于从零开始的索引。这使恢复选定状态更方便。

@IBOutlet weak var METDome_L: MySegmentedControl! 
let key_METDome_L = "METDome_L" 

override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    METDome_L.selectionKey = key_METDome_L 
} 

@IBAction func METDome_Lselect(_ sender: UISegmentedControl) { 
    UserDefaults.standard.set(sender.selectedSegmentIndex, forKey: key_METDome_L) 
} 
+0

辉煌!完全是我所需要的!我将'userDefaults'保存为_strings_的唯一原因是因为每个段都是数字,当我在下一页上调用它时,它会显示数字。但正如你所说,将它们保存为_Int_值并稍后进行转换会更加方便。 –