2016-10-23 14 views
6

Próbuję użyć stałych danych i przygotować się do segregacji razem. To, co mam tak daleko: (1) View ControllerTrwałe dane i przygotuj się na segment

override func viewDidAppear(_ animated: Bool) { 

    let itemsObject = UserDefaults.standard.object(forKey: "items") 


    if let tempItems = itemsObject as? [String] { 

     items = tempItems 

} 

w (View Controller 2):

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if segue.identifier == "toSecondViewController" { 

     let itemsObject = UserDefaults.standard.object(forKey: "items") 

     var items:[String] 

     if let tempItems = itemsObject as? [String] { 

      items = tempItems 

      items.append(textField.text!) 

      print(items) 

     } else { 

      items = [textField.text!] 

     } 

     UserDefaults.standard.set(items, forKey: "items") 


    } 
} 

Ja próbuje dodać element do tablicy na VC2. Następnie chcę przenieść tablicę do VC1, jednocześnie przechowując ją na stałe. Następnie za każdym razem, gdy zamykam i ponownie ładuję aplikację, mogę wydrukować tablicę. Komunikat o błędzie stwierdza "Używanie nierozwiązanych elementów identyfikatora". Używam Xcode 8.0 i Swift 3.0.

enter image description here

enter image description here

+0

Jaki jest dokładnie twój problem? (Także przegapiłeś nawias zamykający w widokuDidAppear) –

+0

Przepraszam, chcę bardzo jasne.Podobno istnieje "Wykorzystanie nierozwiązanych elementów identyfikatora". –

+0

Myślę, że wystarczy utworzyć instancję userdefaults.standard, gdy robisz z nią coś. Np. UserDefaults.standard(). Set (itp. –

Odpowiedz

1

Ok tak dlatego, że chcesz utrzymywać dane ponad uruchomień aplikacji będziesz potrzebować ustawień domyślnych użytkownika do przechowywania twoich przedmiotów. Jak już Dan zasugerował, w zasadzie robisz to dobrze. Chcesz ustawić zmienną, która nie była wcześniej zadeklarowana. Ale pokażę ci to w poniższym kodzie. Dodam także drugie podejście, w którym elementy są przekazywane do następnego kontrolera widoku podczas przeprowadzania segue.

Pierwszy przykład: Wyobraź sobie, że mamy dwa kontrolery widoku, jak w twoim przykładzie. Pierwszy kontroler widoku zawiera UITextField do wprowadzania tekstu użytkownika. Za każdym razem, gdy przełączamy się z pierwszego kontrolera widoku na drugi kontroler widoku za pomocą sortowania scenorysków (np. Po naciśnięciu przycisku), pobieramy istniejące teksty z poprzednich suwaków z ustawień domyślnych użytkownika i dodajemy bieżące dane użytkownika, a następnie kontynuujemy je do ustawień domyślnych użytkownika. Dzieje się tak, w pierwszym kontrolerze widoku:

class ViewController: UIViewController { 

@IBOutlet weak var textField: UITextField! 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    super.prepare(for: segue, sender: sender) 

    if segue.identifier == "toSecondViewController" { 
     let itemsFromDefaults = UserDefaults.standard.object(forKey: "items") 

     var items: [String] 

     if let tempItems = itemsFromDefaults as? [String] 
     { 
      items = tempItems 
      items.append(textField.text!) 
     } 
     else 
     { 
      items = [textField.text!] 
     } 

     print(items) 

     UserDefaults.standard.set(items, forKey: "items") 
    } 
} 
} 

to pierwszy kontroler widoku wygląda całkiem podobny do kodu, ale chciałem, aby dodać go do kompletności.

Następnie w drugim kontrolerem widoku po prostu pobieramy elementy z domyślnych ustawień użytkownika i przechowujemy je bezpośrednio w zmiennej instancji tego kontrolera widoku. Dzięki temu możemy robić, co chcemy w innych metodach w kontrolerze widoku i przetwarzać elementy dalej. Jak powiedziałem, czego brakowało było wystąpienie deklaracja zmiennej do przechowywania przedmiotów w

class ViewController2: UIViewController { 

private var items: [String]? // This is only accessible privately 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    self.items = UserDefaults.standard.object(forKey: "items") as? [String] 
} 

} 

Drugi przykład:. Można również zadeklarować zmienną wewnętrzną/publiczny w ViewController2, dzięki czemu można ustawić go bezpośrednio od pierwszego widzenia kontroler w trybie przedstawienia. Wtedy nie będziesz musiał pobierać elementów z ustawień domyślnych użytkownika w ViewController2. W tym celu można uzyskać dostęp do docelowego kontrolera widoku z segue, a następnie przesłać go do ViewController2 i bezpośrednio ustawić jego elementy.

class ViewController: UIViewController { 

@IBOutlet weak var textField: UITextField! 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    super.prepare(for: segue, sender: sender) 

    if segue.identifier == "toSecondViewController" { 

     let itemsFromDefaults = UserDefaults.standard.object(forKey: "items") 

     var items: [String] 

     // [...] Do the stuff to get the items and add current input like before [...] 

     let destinationViewController = segue.destination as! ViewController2 

     destinationViewController.items = items 
    } 
} 
} 

class ViewController2: UIViewController { 

var items: [String]? // This is accessible from outside now 

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    print(items) // We can now print this because it is set in prepareForSegue 
} 

} 

Naprawdę mam nadzieję, że mogę ci w tym pomóc i wyjaśnić to zrozumiałe. Jeśli masz jakieś pytania, zostaw komentarz.

1

zapomnieć napisać "pozwolić" lub "var" w viewDidAppear. Spróbuj tego:

override func viewDidAppear(_ animated: Bool) { 

    let itemsObject = UserDefaults.standard.object(forKey: "items") 


    if let tempItems = itemsObject as? [String] { 

     let items = tempItems 

    } 
} 

Jeśli chcesz używać przedmiotów po if, trzeba zadeklarować zmienną przed if:

override func viewDidAppear(_ animated: Bool) { 

    let itemsObject = UserDefaults.standard.object(forKey: "items") 

    var items: [String] 
    if let tempItems = itemsObject as? [String] { 

     items = tempItems 
    } 
}