如何从另一个 Class 更改标签和 Table 视图?

How to change Labels and Table View from another Class?

我做了一个应用程序,这个应用程序有几个功能。它有 Table ViewLabelsButtons 等。我在一个名为 SettingsViewController 的 class 中做了一个 Picker View,这对选择语言很有用。我成功了并且运行良好,但我不知道如何更改其他 classes 的 Table ViewLabels 的文本。我没有调用 classes 的经验。

这是我的 class SettingsViewController:

import Foundation
import UIKit

class SettingsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

var languages = ["English", "German", "French"]

var selectedLanguage = 0

@IBOutlet var languageLabel: UILabel!

@IBOutlet var topPartView: UIView!
@IBOutlet weak var languagePicker: UIPickerView!
@IBOutlet var SubmitLanguageButton: UIButton!

@IBAction func pickLanguageButton(sender: AnyObject) {
    //Show Picker
    topPartView.hidden = false
    languagePicker.hidden = false
    SubmitLanguageButton.hidden = false
}

@IBAction func submitLanguageButton(sender: AnyObject) {
    //Hidde Picker
    topPartView.hidden = true
    languagePicker.hidden = true
    SubmitLanguageButton.hidden = true

    if (selectedLanguage == 0) {
       languageLabel.text = "English"
    }
    else if (selectedLanguage == 1) {
       languageLabel.text = "German"
    }
    else if (selectedLanguage == 2) {
       languageLabel.text = "French"
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.


    topPartView.hidden = true
    languagePicker.hidden = true
    SubmitLanguageButton.hidden = true

    languagePicker.delegate = self
    languagePicker.dataSource = self

}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return languages[row]
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return languages.count
}

// returns the number of 'columns' to display.
public func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    selectedLanguage = row
}
}

另一个随机 ViewControllerTable ViewLabel:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

let foodList:[String] = ["Apple", "Bread", "Phineapple", "Water", "Other"]

@IBOutlet weak var myTableView: UITableView!

@IBOutlet var foodTitleLabel: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

    foodTitleLabel.text = "Food"

    myTableView.reloadData()

}


func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    var returnValue = 0

    return returnValue
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let myCell = tableView.dequeueReusableCellWithIdentifier("myCells", forIndexPath: indexPath)


    myCell.textLabel!.text = foodList[indexPath.row]
    myCell.textLabel!.numberOfLines = 0
    return myCell
}
}

那么我要如何将 LabelsTable View 更改为另一个 class,因为每个文本都必须使用在 SettingsViewController 中选择的语言? 例如:当用户选择英文时,所有 ViewController 中的文本必须为英文。 当用户选择法语时,所有 ViewController 中的文本都必须是法语。

如果这个问题不清楚,请告诉我,我会尽量展示更多信息。感谢您的贡献。

您正在尝试使您的应用程序国际化。苹果有一些内置的东西,你应该看看:https://developer.apple.com/internationalization/

如果这不符合您的需要,为了回答您的问题,您的视图应该在加载时 (viewDidLoad) 或在它们出现之前 (viewWillAppear) 设置文本作为用户语言选择的结果,这可能存储在 NSUserDefaults 中。您的设置 class 不应强制对其他视图进行任何更改,您的其他视图应在显示之前将自己的文本设置为正确的语言。

struct Localization {

    static func stringsForScreen(screenName:String, forLanguage language:String) -> [String:String] {
        //parse a file that has the strings for the given screen in the given language, and return it
    }
}

class HomeViewController:UIViewController {
    @IBOutlet var titleLabel:UILabel?
    @IBOutlet var bodyLabel:UILabel?

    override func viewDidLoad() { //or possibly viewDidAppear, depends on your needs
        super.viewDidLoad()

        let language = NSUserDefaults.standardUserDefaults().stringForKey("currentLanguage") ?? "English"

        let textDict = Localization.stringsForScreen("HomeViewController" forLanguage:language)

        titleLabel.text = textDict["titleLabelText"] ?? ""
        bodyLabel.text = textDict["bodyLabelText"] ?? ""
    }
}

class PickLanguageViewController:UIViewController, UIPickerViewDelegate {
    var languages = ["English","French","Spanish"]
    //Whatever method the picker uses
    func pickerView(pickerView:UIPickerView didSelectRow row:Int inComponent component:Int) {
        NSUserDefaults.standardUserDefaults().setObject(languages[row] forKey:"currentLanguage")
    }
}

这可能是如何构造的骨架示例。

所以你可以通过不同的方法解决这个问题,但就我的观点而言,最简单的方法是实现一个协议来处理 viewcontroller 中的事件并对另一个事件产生影响,例如

protocol ChangeLanguagesProtocol
{
   func returnNewLanguages(newlanguages:[String])
}

那么您需要在 viewcontroller 中实现协议及其方法,例如

  class SettingsViewController: UIViewController, 
  UIPickerViewDelegate, UIPickerViewDataSource , ChangeLanguagesProtocol {


  var languages = ["English", "German", "French"]

  func returnNewLanguages(newlanguages:[String]){
       self.languages = newlanguages
  }

然后在你的第二个 ViewController class 你需要有一个协议类型的 var 并在需要时触发它的方法

  //variable
  var delegate:ChangeLanguagesProtocol!

  //for example when clicking a button 
  @IBAction func SampleButtonPress(sender:UIButton){

  let newlanguages:[String] = ["Spanish", "Chinesse", "German", "French", "Other"]
      delegate.returnNewLanguages(newlanguages)
  }

最后一步,当我们要推送到所需的 viewcontroller 时,我们需要分配委托变量,如果 viewcontroller 彼此不相邻,您可以使用单例或一个共享实例来维护你的委托 属性 直到你需要它,但它看起来像

// this should be in your first ViewController
  @IBAction func gotoNextViewController(sender:UIButton){

    let _localization = Localization(nibName: "Localization", bundle:nil)
    _localization .delegate = self
    self.navigationController?.pushViewController(_localization , animated: true)
  }

我找到了解决方案。首先变量 selectedLanguage 我在 class SettingsViewController.

中声明了它
import UIKit

var selectedLanguage = 0 //<<< Here

class SettingsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

var languages = ["English", "German", "French"]

之后,我在方法 viewDidLoad 中对每个 ViewController 执行了此操作(我将只显示一个 ViewController)。

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.


    if (selectedLanguage == 0) { //English
        foodTitleLabel.text = "Food"
        foodList = ["Apple", "Bread", "Pineapple", "Water", "Other"]
    }
    else if (selectedLanguage == 1) { //German
        foodTitleLabel.text = "Lebensmittel"
        foodList = [ "Apfel", "Brot", "Pineapple", "Wasser","Andere"]
    }
    if (selectedLanguage == 2) { //French
        foodTitleLabel.text = "Aliments"
        foodList = ["Pomme", "Pain", "Ananas", "Eau", "Autre"]
    }

我希望这对其他用户有所帮助,因为它对我来说非常有效。

我们可以用更少的代码以更简洁的方式完成此操作,例如:

enum names{
case English, German, French
func food() -> String {
    switch self {
     case English: return "food"
     case German: return "Lebensmittel"
     case French: return "Aliments"
    }
 }

func foodList() -> [] {
    switch self {
     case English: return ["Apple", "Bread", "Pineapple", "Water", "Other"]
     case German: return [ "Apfel", "Brot", "Pineapple", "Wasser","Andere"]
     case French: return ["Pomme", "Pain", "Ananas", "Eau", "Autre"]
    }
 }
}

import UIKit

var lang = names.English

class SettingsViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    foodTitleLabel.text = lang.food()
    foodList = lang.foodList()