有没有比isHidden = true / false更好的方式来显示和隐藏链接到分段控件的多个textview?

问题描述 投票:0回答:4

初学者在这里,我创建了一个带有3个分段控件的VC,每个控件有3个段。每个段选择显示不同的文本视图。在任何给定时间,显示2个分段控件,因此您可以选择在6个文本视图中的任何一个之间切换。总共有9个文本视图。

我现在写这个的方式在模拟器中看起来有点小问题,所以我想知道一种更好的方法来编写这种重复代码。我在任何时候显示的2/3分段控件的所有选择之间有很多.isHidden = false和isHidden = true行。谁能告诉我怎样才能以更安全的方式写出来?如果你想举一个简短的例子或者告诉我谷歌的内容,我很感激。

这就是我所拥有的:

class ViewController: UIViewController {

    @IBOutlet weak var segmentedControl: UISegmentedControl!
    @IBOutlet weak var textSegmentedControl: UISegmentedControl!
    @IBOutlet weak var translationSegmentedControl: UISegmentedControl!
    @IBOutlet weak var firstLangText: UITextView!
    @IBOutlet weak var secondLangText: UITextView!
    @IBOutlet weak var thirdLangText: UITextView!
    @IBOutlet weak var translationA: UITextView!
    @IBOutlet weak var translationB: UITextView!
    @IBOutlet weak var translationC: UITextView!
    @IBOutlet weak var textInfo: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        style(control: segmentedControl)

        segmentedControl.addTarget(self, action: #selector(updateMainSegmentedControl), for: .valueChanged)
        textSegmentedControl.addTarget(self, action: #selector(updateTextSegmentedControl), for: .valueChanged)
        translationSegmentedControl.addTarget(self, action: #selector(updateTranslationSegmentedControl), for: .valueChanged)

        secondLangText.isHidden = true
        thirdLangText.isHidden = true
        translationSegmentedControl.isHidden = true
        translationA.isHidden = true
        translationB.isHidden = true
        translationC.isHidden = true
}

    //Mark: Stye SegmentControls & underlineBar
    func style(control: UISegmentedControl) {
        control.backgroundColor = .clear
        control.tintColor = .clear
        control.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16), NSAttributedStringKey.foregroundColor: UIColor.secondaryColor], for: .normal)
        control.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16),NSAttributedStringKey.foregroundColor: UIColor.primaryColor], for: .selected)
    }

    @IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            textSegmentedControl.isHidden = false
            translationSegmentedControl.isHidden = true
            translationUnderlineBar.isHidden = true
            firstLangText.isHidden = false
            translationA.isHidden = true
            textInfo.isHidden = true
        case 1:
            textSegmentedControl.isHidden = true
            translationSegmentedControl.isHidden = false
            firstLangText.isHidden = true
            translationA.isHidden = false
            textInfo.isHidden = true
        case 2:
            textSegmentedControl.isHidden = true
            translationSegmentedControl.isHidden = true
            firstLangText.isHidden = true
            textInfo.isHidden = false
        default:
            break;
        }
    }

    @IBAction func selectTextLanguage(_ sender: UISegmentedControl) {
        switch textSegmentedControl.selectedSegmentIndex {
        case 0:
            firstLangText.isHidden = false
            secondLangText.isHidden = true
            thirdLangText.isHidden = true
            translationA.isHidden = true
            translationB.isHidden = true
            translationC.isHidden = true
        case 1:
            firstLangText.isHidden = true
            secondLangText.isHidden = false
            thirdLangText.isHidden = true
            translationA.isHidden = true
            translationB.isHidden = true
            translationC.isHidden = true
        case 2:
            firstLangText.isHidden = true
            secondLangText.isHidden = true
            thirdLangText.isHidden = false
            translationA.isHidden = true
            translationB.isHidden = true
            translationC.isHidden = true
        default:
            break;
        }
    }

    @IBAction func selectTranslationLanguage(_ sender: UISegmentedControl) {
        switch translationSegmentedControl.selectedSegmentIndex {
        case 0:
            translationA.isHidden = false
            translationB.isHidden = true
            translationC.isHidden = true
            firstLangText.isHidden = true
            secondLangText.isHidden = true
            thirdLangText.isHidden = true
        case 1:
            translationA.isHidden = true
            translationB.isHidden = false
            translationC.isHidden = true
            firstLangText.isHidden = true
            secondLangText.isHidden = true
            thirdLangText.isHidden = true
        case 2:
            translationA.isHidden = true
            translationB.isHidden = true
            translationC.isHidden = false
            firstLangText.isHidden = true
            secondLangText.isHidden = true
            thirdLangText.isHidden = true
        default:
            break;
        }
    }
ios swift
4个回答
0
投票

您可以在切换之前将它们全部设置为默认值,然后只更新案例中的不同值。这在您的第三种方法中尤其有效,其中大多数视图的默认状态为true。

@IBAction func selectTranslationLanguage(_ sender: UISegmentedControl) 
{
    [translationA, translationB, translationC, firstLangText,
     secondLangText, thirdLangText].forEach { $0.isHidden = true }

    switch translationSegmentedControl.selectedSegmentIndex 
    {
        case 0: translationA.isHidden = false
        case 1: translationB.isHidden = false
        case 2: translationC.isHidden = false
        default: break
    }
}

0
投票

首先,您需要从switch case中提取常见的行为,以便删除一些重复的行为。

   @IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
        switch segmentedControl.selectedSegmentIndex {
        case 0:
            translationUnderlineBar.isHidden = true
            textInfo.isHidden = true
            firstLangText.isHidden = false
            translationA.isHidden = true
            textSegmentedControl.isHidden = false
            translationSegmentedControl.isHidden = true
        case 1:
            textInfo.isHidden = true
            firstLangText.isHidden = true
            translationA.isHidden = false
            textSegmentedControl.isHidden = true
            translationSegmentedControl.isHidden = false
        case 2:
            textInfo.isHidden = false
            firstLangText.isHidden = true
            textSegmentedControl.isHidden = true
            translationSegmentedControl.isHidden = true
        default:
            break;
        }
    }

    @IBAction func selectTextLanguage(_ sender: UISegmentedControl) {
        switch textSegmentedControl.selectedSegmentIndex {
        case 0:
            showLanaguage(which: firstLangText)
        case 1:
            showLanaguage(which: secondLangText)
        case 2:
            showLanaguage(which: thirdLangText)
        default:
            break;
        }
        translationA.isHidden = true
        translationB.isHidden = true
        translationC.isHidden = true
    }

    func showLanaguage(which: UITextView){
        [firstLangText,secondLangText,thirdLangText].forEach({
            $0?.isHidden = $0 != which
        })
    }

    func showTranslation(which: UITextView){
        [translationA,translationB,translationC].forEach({
            $0?.isHidden = $0 != which
        })
    }

    @IBAction func selectTranslationLanguage(_ sender: UISegmentedControl) {
        switch translationSegmentedControl.selectedSegmentIndex {
        case 0:
            showTranslation(which: translationA)
        case 1:
            showTranslation(which: translationB)
        case 2:
            showTranslation(which: translationC)
        default:
            break;
        }
        firstLangText.isHidden = true
        secondLangText.isHidden = true
        thirdLangText.isHidden = true
    }

0
投票

如果文本视图具有相同的位置,则可以重复使用它们。如果它们不同,您可以使用outlet集合对它们进行分组。所以你会有

@IBOutlet weak var langTextViews: [UITextView]!

代替:

@IBOutlet weak var firstLangText: UITextView!
@IBOutlet weak var secondLangText: UITextView!
@IBOutlet weak var thirdLangText: UITextView!

它将使您的代码更有条理和可读。您可以优化textView隐藏/显示部分。例如,textOrTranslationChange mehtod看起来像这样:

@IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
  textSegmentedControl.isHidden = (segmentedControl.selectedSegmentIndex != 0)
  langTextViews[0].isHidden = (segmentedControl.selectedSegmentIndex != 0)
  translationSegmentedControl.isHidden = (segmentedControl.selectedSegmentIndex != 1)
  textInfo.isHidden = (segmentedControl.selectedSegmentIndex != 2)
  etc...
}

0
投票

优雅的解决方案是使用UISegmentedControl的美丽。 Swift Dictionaries和标签属性。

您可以通过设置分段控件的初始UITextView来使用单个tag,然后引用tagselectedIndex来确定要更改的字段或值。然后,您可以轻松地将值存储在Dictionary中,而无需复杂的switch语句。

这是一个最小的,可重复的例子。你应该在输入之后实现自己的处理值的方法,比如验证。

import Foundation
import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    // Properties

    var activeSegment: UISegmentedControl?
    var activeIndex: Int?

    var values:[String: String] = [:]


    lazy var segmentedController: UISegmentedControl = {
        let seg = UISegmentedControl(items: ["Name", "Age", "Language"])
        seg.translatesAutoresizingMaskIntoConstraints = false
        seg.tag = 0
        seg.addTarget(self, action: #selector(segmentedControllerValueChanged(sender:)), for: .valueChanged)
        return seg
    }()

    lazy var secondSegmentedController: UISegmentedControl = {
        let seg = UISegmentedControl(items: ["Type", "Kind", "Thing"])
        seg.translatesAutoresizingMaskIntoConstraints = false
        seg.tag = 1
        seg.addTarget(self, action: #selector(segmentedControllerValueChanged(sender:)), for: .valueChanged)
        return seg
    }()

    let textField: UITextField = {
        let tf = UITextField(frame: CGRect.zero)
        tf.translatesAutoresizingMaskIntoConstraints = false
        tf.placeholder = "Select Field"
        return tf
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
        self.layoutSubviews()

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

    func layoutSubviews() {
        let guide = self.view.safeAreaLayoutGuide
        let spacing:CGFloat = 12.0

        self.view.addSubview(segmentedController)
        self.view.addSubview(secondSegmentedController)
        self.view.addSubview(textField)

        segmentedController.widthAnchor.constraint(equalTo: guide.widthAnchor).isActive = true
        segmentedController.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
        segmentedController.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -spacing).isActive = true
        segmentedController.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true

        secondSegmentedController.widthAnchor.constraint(equalTo: guide.widthAnchor).isActive = true
        secondSegmentedController.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
        secondSegmentedController.bottomAnchor.constraint(equalTo: segmentedController.topAnchor, constant: -spacing).isActive = true
        secondSegmentedController.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true

        textField.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true
        textField.centerYAnchor.constraint(equalTo: guide.centerYAnchor).isActive = true
        textField.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
        textField.widthAnchor.constraint(equalTo: guide.widthAnchor, constant: -spacing*2).isActive = true

    }

    @objc func segmentedControllerValueChanged(sender: UISegmentedControl) {
        // Clear all other segments
        let segmentedcontrols = [segmentedController, secondSegmentedController]
        segmentedcontrols.forEach { (control) in
            if (control.tag != sender.tag) {
                control.selectedSegmentIndex = -1
            }
        }
        // Safely get the title for the index
        guard  let titleForIndex = sender.titleForSegment(at: sender.selectedSegmentIndex) else {
            self.textField.placeholder = "Select Field"
            return
        }

        // Set the active fields.
        self.textField.text = nil
        self.textField.placeholder = "Input " + titleForIndex
        self.activeSegment = sender
        self.activeIndex = sender.selectedSegmentIndex

        // Handle Text Input with your own methods / switch statements


        print("Value did change to: \( sender.selectedSegmentIndex) with tag \(sender.tag)" )
        print("values: \(values)")

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    //MARK: - Text Field Delegate

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // Safely get the title for the index

        guard let segment = activeSegment, let index = activeIndex, let activeSegmentTitle = segment.titleForSegment(at: index) else {
            return false
        }

        guard let text = textField.text else {
            return false
        }

        values[activeSegmentTitle] = text

        textField.resignFirstResponder()
        return true
    }
}

View and Output Diagram

© www.soinside.com 2019 - 2024. All rights reserved.