Demo entry 5907747

EinstellungenView

   

Submitted by anonymous on Aug 31, 2016 at 18:41
Language: Swift. Code size: 33.9 kB.

//
//  ViewController.swift
//  DynamicUI
//
//  Created by Jan Kartschewski on 23.03.16.
//  Copyright © 2016 Jan Kartschewski. All rights reserved.
//

import UIKit
import CoreData

class EinstellungenViewController: UIViewController, UIAlertViewDelegate, NSFetchedResultsControllerDelegate, UITextFieldDelegate  {
    
    @IBOutlet weak var scrollView: UIScrollView!
    
    //NSMutableArray() wird als Typ für die spätere verarbeitung im Framework (Core Data) benötigt
    var gespeicherte_Studenten = NSMutableArray()
    
    // Vertikaler Abstand in dem die erste Reihe von UI-Elementen erzeugt wird
    var startingOffset : CGFloat = -40
    
    //Variable zum erstellen der Badge
    var customBadge : CustomBadge?
    
    //Speichern der Bildschirmgröße
    var screenSize : CGRect = UIScreen.mainScreen().bounds
    
    //Wird benötigt um die Eingaben im Textfield vom PopUp sichern zu können
    var inputTextField : UITextField?
    
   
    //
    //Methode um bei einem Orientierungswechsel das UI entsprechend neu zu erzeugen. Funktioniert fehlerfrei nur in iOS8
    //
    @available(iOS 8,*)
    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animateAlongsideTransition(nil, completion: { _ in
            self.screenSize = UIScreen.mainScreen().bounds
            self.deleteSubviews()
            self.configureView()
        
        })
    }
    
//    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool{
//    if notificationSettings.types != .None {
//      application.registerForRemoteNotifications()
//    }
    
    
    //
    //Wird aufgerufen sobald die View geladen wurde. Hier werden dann die bereits gespeicherten Datensätze geladen. Sollten noch keine vorhanden sein, so wird dem Nutzer
    //über ein Alert die Funktionsweise mitgeteilt. In jedem Fall wird dann über "configureView()" das UI für die View erzeugt. Des Weiteren wird zuletzt dafür gesorgt, dass
    //durch einen "Tap" auf das Display die Tastatur geschlossen werden kann.
    //
    override func  viewDidLoad() {
        super.viewDidLoad()
        loadData() //Hier werden die vorher gespeicherten Daten geladen
        if (gespeicherte_Studenten.count == 0){
            showAlertViewWithTitle("Willkommen!", message: "Bitte weise dem Hauptnutzer deine Matrikelnummer zu, da in der Klausurenübersicht nur die Klausuren des Hauptnutzers angezeigt werden. Die Auswahl einer Klausur zeigt Dir den akuellen Stand der Korrektur Deiner sowie der Deiner hinzugefügten Freunde an.")
            
        } else {
            
            print("Es wurde etwas vorher gespeichert!")
            print(gespeicherte_Studenten[0])
        }
        
        configureView() //Aufruf zur Generierung der Oberfläche
        //Hier wird dafür gesorgt, dass durch die Geste "Tap" auf der Oberfläche das Keyboard geschlossen wird
        let tap : UIGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
        view.addGestureRecognizer(tap)
    }
    
    //
    //Die Benutzerverwaltung (=EinstellungenView) ist standardmäßig der Einstieg in die App. Sollten jedoch bereits
    //Datensätze vorhanden sein, so soll direkt die Klausurenübersicht angezeigt werden
    //
    override func viewWillAppear(animated: Bool) {
        loadData() //Hier werden die vorher gespeicherten Daten geladen
        if(gespeicherte_Studenten.count != 0){
            tabBarController?.selectedIndex = 1
        }
        
    }
    
    
    //
    //
    //
    override func viewDidLayoutSubviews() {
        scrollView.contentSize.height = screenSize.height //Angabe wie groß die verfügbare Fläche ist die scrollbar sein soll
        
    }
    
    //
    //Die Methode, die das gesamte UI abhängig von der Anzahl der Datensätze für die Benutzerverwaltung erstellt.
    //
    func configureView(){
        print("Anzahl der gespeicherten Studenten: \(gespeicherte_Studenten.count)")
        startingOffset = -40
        if (gespeicherte_Studenten.count == 0){ //Wenn noch nichts gespeichert wurde wird hier nur die erste Zeile erzeugt
            
            createLabel(true)
            createBadge()
            createTextField(1)
            createAddButton(1)
            
        } else {
            
            for index in 1...(gespeicherte_Studenten.count+1){ //Falls schon Studenten gespeichert wurden
                if (index <= gespeicherte_Studenten.count){//wird hier für jeden gespeicherten Studenten eine Zeile erzeugt
                    if (index == 1){
                        createLabel(true)
                        createBadge()
                        createTextField(index)
                        createAddButton(index)
                        startingOffset += 20 //Erzeugt einen größeren Abstand zwischen Hauptnutzer und Freunden
                        createLabel(false)
                    } else{
                    createBadge()
                    createTextField(index)
                    createAddButton(index)
                    createRemoveButton(index)
                    }
                    
                } else { //und eine Zeile für die Eingabe eines neuen Studenten
                    
                    createBadge()
                    createTextField(index)
                    createAddButton(index)
                    
                }
            }
        }
    }
    
    //
    //Methoden um das UI zu erzeugen
    //
    
    
    //
    //Methode um die für das UI benötigten Labels zu erzeugen. Entweder wird das Label für den Hauptnutzer (mainStudent=true) erzeugt oder das Label für die Freunde (mainStudent=false).
    //Da das UI zur Laufzeit erzeugt wird, müssen die Constraints für die UI-Elemente im Code angegeben werden. Die Labels werden als Subviews der "scrollView" hinzugefügt
    //
    func createLabel(mainStudent : Bool){
        if(mainStudent){
            let label = UILabel()
            label.text = "Hauptnutzer"
            label.textAlignment = .Center
            self.scrollView.addSubview(label)
    
            let centerConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0)
            let pinTop = NSLayoutConstraint(item: label, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1.0, constant: startingOffset)
            
            label.translatesAutoresizingMaskIntoConstraints = false

            scrollView.addConstraint(centerConstraint)
            scrollView.addConstraint(pinTop)
            
            startingOffset+=30
        } else {
            let label = UILabel()
            label.text = "Freunde"
            label.textAlignment = .Center
            self.scrollView.addSubview(label)
            
            let centerConstraint = NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0)
            let pinTop = NSLayoutConstraint(item: label, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1.0, constant: startingOffset)
            label.translatesAutoresizingMaskIntoConstraints = false
            
            scrollView.addConstraint(centerConstraint)
            scrollView.addConstraint(pinTop)
            
 
            startingOffset+=30
        }
    }
    
    
    //
    //Methode um die Textfelder zu erzeugen. Die Methode erstellt Textfelder in Abhängigkeit davon, ob das Textfeld für einen alten oder neuen Datensatz ist. Ist es für einen alten
    //Datensatz so wird der angegebene Name für die Matrikelnr. im Textfeld angezeigt. Andernfalls wird der Platzhaltertext "Matrikelnr." angezeigt. In jedem Fall müssen dem erzeugten
    //Textfeld wieder Constraints zugewiesen werden, um im Betrieb die Korrekte Position und Größe zu haben. Zuletzt wird das erzeugte Textfeld als Subview von "customBadge" hinzugefügt.
    //"customBadge" ist eine modifzierte View in der jeweils ein Datensatz mit den zugehörigen UI-Elementen angezeigt wird. Sie ist somit auch eine Subview und zwar von "scrollView".
    //
    func createTextField(index : Int){
        let matrikelTextField = UITextField()
        
        //Wenn das Textfeld nicht für die aktuell letzte Zeile erzeugt werden soll, dann wird die zugehörige (=index) Matrikelnr. im Textfeld angezeigt
        if (index<=gespeicherte_Studenten.count){
            let student = gespeicherte_Studenten[index-1] as? Student
            
            matrikelTextField.tag = index
            matrikelTextField.text = student?.name
            matrikelTextField
            //matrikelTextField.enabled = false
            matrikelTextField.layer.borderColor = (UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1.0)).CGColor
            matrikelTextField.layer.borderWidth = 1
            matrikelTextField.borderStyle = UITextBorderStyle.Line
            matrikelTextField.clearButtonMode = UITextFieldViewMode.WhileEditing
            matrikelTextField.textAlignment = .Center
            self.customBadge!.addSubview(matrikelTextField)
            matrikelTextField.delegate = self
            matrikelTextField.keyboardType = UIKeyboardType.NumberPad
        }
        else {//andernfalls wird ein Textfeld mit dem Platzhaltertext "Matrikelnr." erzeugt
            matrikelTextField.tag = index
            matrikelTextField.placeholder = "Matrikelnr."
            matrikelTextField.layer.borderColor = (UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1.0)).CGColor
            matrikelTextField.layer.borderWidth = 1
            matrikelTextField.borderStyle = UITextBorderStyle.Line
            matrikelTextField.clearButtonMode = UITextFieldViewMode.WhileEditing
            matrikelTextField.textAlignment = .Center
            self.customBadge!.addSubview(matrikelTextField)
            matrikelTextField.delegate = self
            matrikelTextField.keyboardType = UIKeyboardType.NumberPad
        }
        
        let leadingConstraint = NSLayoutConstraint(item: matrikelTextField, attribute: .Leading, relatedBy: .Equal, toItem: customBadge!, attribute: .Leading, multiplier: 1, constant: 50)
        let trailingConstraint = NSLayoutConstraint(item: matrikelTextField, attribute: .Trailing, relatedBy: .Equal, toItem: customBadge!, attribute: .Trailing, multiplier: 1, constant: -50)
        let centerConstraint = NSLayoutConstraint(item: matrikelTextField, attribute: .CenterY, relatedBy: .Equal, toItem: customBadge!, attribute: .CenterY, multiplier: 1, constant: 0)
        
        matrikelTextField.translatesAutoresizingMaskIntoConstraints = false

        customBadge!.addConstraint(trailingConstraint)
        customBadge!.addConstraint(leadingConstraint)
        customBadge!.addConstraint(centerConstraint)
        
    }
    
    
    //
    //Methode, die die Erzeugung des AddButtons implementiert. Ihr wird als Parameter der Zeilenindex übergeben, um ihn in der "Titel"-Eigenschaft des erstellten Buttons,
    //zu speichern. Wird ein AddButton später betätigt so lässt sich durch das Auslesen der "Titel"-Eigenschaft bestimmen auf welche Zeile im UI (=Datensatz) sich die Aktion 
    //bezieht. Es wird festgelegt, dass durch einen Click auf einen AddButton die Methode "addStudent()" ausgeführt werden soll. Ansonsten werden hier wie bei den anderen UI-Elementen
    //Constraints festgelegt und das neue UI-Element wird der View "customBadge" hinzugefügt, die eine Subview von "scrollView" ist.
    //
    func createAddButton(index : Int){
        let addButton = CustomButton()
        
        addButton.setAddButton()
        addButton.titleLabel?.layer.opacity = 0.0
        addButton.setTitle("\(index)", forState: UIControlState.Normal)
        addButton.addTarget(self, action: "addStudent:", forControlEvents: UIControlEvents.TouchUpInside)
        self.customBadge!.addSubview(addButton)
        
        
        let widthConstraint = NSLayoutConstraint(item: addButton, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 28)
        let heightConstraint = NSLayoutConstraint(item: addButton, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 28)
        let trailingConstraint = NSLayoutConstraint(item: addButton, attribute: .Trailing, relatedBy: .Equal, toItem: customBadge!, attribute: .Trailing, multiplier: 1, constant: -15)
        let centerConstraint = NSLayoutConstraint(item: addButton, attribute: .CenterY, relatedBy: .Equal, toItem: customBadge!, attribute: .CenterY, multiplier: 1, constant: 0)
        
        addButton.translatesAutoresizingMaskIntoConstraints = false
        
        customBadge!.addConstraint(widthConstraint)
        customBadge!.addConstraint(heightConstraint)
        customBadge!.addConstraint(trailingConstraint)
        customBadge!.addConstraint(centerConstraint)
    }
    
    //
    //Methode, die die Erzeugung des RemoveButtons implementiert. Ihr wird als Parameter der Zeilenindex übergeben, um das negative Pendant in der "Titel"-Eigenschaft des 
    //erstellten Buttons, zu speichern. Wird ein RemoveButton später betätigt so lässt sich durch das Auslesen der "Titel"-Eigenschaft bestimmen auf welche Zeile im UI (=Datensatz) sich 
    //die Aktion bezieht. Es wird festgelegt, dass durch einen Click auf einen AddButton die Methode "removeStudent()" ausgeführt werden soll. Ansonsten werden hier wie bei den anderen 
    //UI-Elementen Constraints festgelegt und das neue UI-Element wird der View "customBadge" hinzugefügt, die eine Subview von "scrollView" ist.
    //
    func createRemoveButton(index : Int){
        let removeButton = CustomButton()
        
        removeButton.titleLabel?.layer.opacity = 0.0
        removeButton.setTitle("\(-index)", forState: UIControlState.Normal)
        removeButton.addTarget(self, action: "removeStudent:", forControlEvents: UIControlEvents.TouchUpInside)
        self.customBadge!.addSubview(removeButton)
        
        let widthConstraint = NSLayoutConstraint(item: removeButton, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 28)
        let heightConstraint = NSLayoutConstraint(item: removeButton, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 28)
        let leadingConstraint = NSLayoutConstraint(item: removeButton, attribute: .Leading, relatedBy: .Equal, toItem: customBadge!, attribute: .Leading, multiplier: 1, constant: 15)
        let centerConstraint = NSLayoutConstraint(item: removeButton, attribute: .CenterY, relatedBy: .Equal, toItem: customBadge!, attribute: .CenterY, multiplier: 1, constant: 0)
        
        removeButton.translatesAutoresizingMaskIntoConstraints = false
        
        customBadge!.addConstraint(widthConstraint)
        customBadge!.addConstraint(heightConstraint)
        customBadge!.addConstraint(leadingConstraint)
        customBadge!.addConstraint(centerConstraint)
        
        
    }
    
    //
    //Methode, die die Erzeugung einer modifizierten View (CustomBadge.swift) implementiert. Sie ist visuell gesehen ein Kasten, dem später die relevanten UI-Elemente hinzugefügt werden.
    //
    func createBadge(){
        customBadge = CustomBadge()
        self.scrollView.addSubview(customBadge!)
        
        let leadingConstraint = NSLayoutConstraint(item: customBadge!, attribute: .Leading, relatedBy: .Equal, toItem: scrollView, attribute: .Leading, multiplier: 1, constant: 20)
        let widthConstraint = NSLayoutConstraint(item: customBadge!, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: screenSize.width - 40)
        let heightConstraint = NSLayoutConstraint(item: customBadge!, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 57)
        let pinTop = NSLayoutConstraint(item: customBadge!, attribute: .Top, relatedBy: .Equal, toItem: scrollView, attribute: .Top, multiplier: 1, constant: startingOffset)
        
        //Hier wird im Grunde Auto-Layout deaktivert, damit die hier festgelegten Constraints nicht ignoriert werden
        customBadge!.translatesAutoresizingMaskIntoConstraints = false
        
        scrollView.addConstraint(widthConstraint)
        scrollView.addConstraint(leadingConstraint)
        scrollView.addConstraint(heightConstraint)
        scrollView.addConstraint(pinTop)
        
        startingOffset += 70
    }
    
    //
    //Methoden um UI-Elemente zu erzeugen Ende
    //
    
    
    
    
    //
    //Methoden für die Add-/Remove-Buttons
    //
    
    //Methode die durch drücken des RemoveButtons aktiviert wird. Sie entfernt den jeweiligen Studenten und läd im Anschluss das aktuallisierte UI
    func removeStudent(sender: UIButton!){
        sender.selected = true //Feedback das Button gedrückt wurde
        
        let index : Int? = Int((sender.titleLabel?.text)!)! * (-1) //Hier wird über den Titel des Buttons der Index (=Student/Stelle im Array) ermittelt
        print("Index lautet: \(index! - 1)")
        
        //Referenz auf das in AppDelegate automatisch angelegte managedObjectContext (=persistenter Speicherort)
        let appDel : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let moc : NSManagedObjectContext = appDel.managedObjectContext
        
        moc.deleteObject(gespeicherte_Studenten[index!-1] as! NSManagedObject) //Hier wird der gewünschte Student aus moc entfernt
        gespeicherte_Studenten.removeObjectAtIndex(index!-1) //Hier wird der gewünschte Student aus dem Array entfernt (nötig?)
        do{
            try moc.save() //Hier wird die Änderung am moc gespeichert
            deleteSubviews() //Hier wird die Methode zur Löschung aller SubViews in der ScrollView aufgerufen um das UI dann neu zu zeichnen
            
        } catch {
            
        }
        
        
        
    }
    
    //
    //Methode die durch drücken des AddButtons aktiviert wird. Sie fügt entweder einen neuen Studenten dem persistenten Speicher hinzu oder aktuallisiert den 
    //Eintrag für einen vorhandenen Studenten. Anhand der "title"-Eigenschaft vom übergebenen Parameter "sender" wird die zugehörige Zeile des gedrückten Buttons
    //ermittelt. Dadurch lässt sich ein Verweis auf das zugehörige Textfeld erstellen. Der Zeilenindex bestimmt, ob ein neuer Datensatz angelegt (index > Anzahl gespeicherter Studenten)
    //wird oder ob ein bereits gespeicherter Datensatz aktualisiert werden soll (index <= Anzahl gespeicherter Studenten). In beiden Fällen wird durch die Methode "validInput()"
    //überprüft, ob die Eingabe alle Vorgaben dieser Methode erfüllt. Sollte dies der Fall sein wird entweder die Methode "writeData()" um einen neuen Datensatz zu speicher oder
    //die Methode "updateEntity()" um den ausgewählten Datensatz (=Zeilenindex) zu aktualisieren.
    //vorhandener aktualisiert werden soll.
    //
    func addStudent(sender: UIButton!){
        sender.selected = true //Feedback das Button gedrückt wurde
        
        let tag : Int? = Int((sender.titleLabel?.text)!) //Hier wird über den Titel des Buttons der Index (=Student/Stelle im Array) ermittelt
        let textfield : UITextField = self.scrollView.viewWithTag(tag!) as! UITextField //nun wird ein Verweis auf das jeweilige TextField geholt
        print("Eingabe im Textfield: \(textfield.text)")
        print ("Tag lautet \(tag!) und Anzahl Studenten: \(gespeicherte_Studenten.count)")
        
        if (tag<=gespeicherte_Studenten.count){ //sollte der angegebene Zeilen-Index kleiner oder gleich der Anzahl der gespeicherten Studenten sein, dann soll der betreffende Eintrag geupdatet werden
            
            //Ist Eingabe gültig?
            if (validInput(textfield.text!)){
                updateEntity(tag!)
                
            }
        } else {//wenn es die aktuell letzte Zeile der UI-Elemente ist, dann...
            print (textfield.text)
            
            //Ist Eingabe gültig?
            if validInput(textfield.text!){
                writeData(textfield.text!)
                
            }
        }
    }
    
    //
    //Ende Methoden für Add-/Remove-Buttons
    //
    
    
    
    //
    //Methode um die Matrikelnummer eines bereits vorhandenen Eintrags zu ändern. Bekommt den Zeilenindex in dem der relevante Datensatz angezeigt wird als Parameter übergeben.
    //Mit Hilfe des Indexes wird der zu aktualisierende Datensatz ermittelt und die Eigenschaften "name" und "matrikelnummer" mit den neuen Werten aktualisiert. Diese Änderungen werden
    //abschließend persistent gespeichert.
    //
    func updateEntity(index : Int){
        
        //Referenz auf das in AppDelegate automatisch angelegte managedObjectContext (=persistenter Speicherort)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let moc = appDelegate.managedObjectContext
        
        
        let student = gespeicherte_Studenten[index-1] as! Student //Referenz auf das zu aktualliserende Objekt
        let fetchRequest = NSFetchRequest(entityName: "Student") //Festlegen welche Entität relevant ist für die Suche
        fetchRequest.predicate = NSPredicate(format: "matrikelnummer = %@", student.matrikelnummer!) //Festlegen nach welcher Matrikelnummer gesucht werden soll
        
        do{
            if let fetchResults = try appDelegate.managedObjectContext.executeFetchRequest(fetchRequest) as? [NSManagedObject]{ //Referenz auf alle gefundenen Objekte
                if (fetchResults.count != 0){ //wenn es mindestens 1 Objekt gibt, dann...
                    let managedObject = fetchResults[0] //Referenz auf das gefundene Objekt
                    let textField = self.view.viewWithTag(index) as! UITextField //Referenz auf das TextField mit der neuen Matrikelnummer
                    managedObject.setValue(textField.text, forKey: "matrikelnummer") //dem Objekt die neue Matrikelnummer zuweisen
                    showAlertViewWithTextfield("Zugehöriger Name?", message: "Bitte gib einen Namen für die Matrikelnr. an", withText: true){ (result) -> () in //PopUp zur Vergabe eines Aliases
                        if (result.characters.count == 0){
                            managedObject.setValue(textField.text, forKey: "name")
                        }
                        else {
                            managedObject.setValue(self.inputTextField!.text, forKey: "name")
                        }
                        self.deleteSubviews()
                    }
                    print(inputTextField!.text)
                    
                }
            }
        }catch {
            
        }
        
        do {
            try moc.save() //Änderungen im persistenten Speicher sichern
        } catch {}
        
        
    }
    
    //
    //Methode um alle Subviews in ScrollView zu löschen und dann das aktuallisierte UI darzustellen. Wird prinzipiell nach jeder Änderung am UI (Hinzufügen, Aktualisieren und Löschen von
    //Datensätzen) ausgeführt.
    //
    func deleteSubviews(){
        //Löschen aller Buttons und Textfields und im Anschluss UI erneut erstellen lassen
        let subViews = self.scrollView.subviews
        for subView in subViews {
            if ((subView is UIButton) || (subView is UITextField || (subView is CustomBadge) || (subView is UILabel))){ //Wenn subView vom Typ Button oder Textfield ist wird sie von ScrollView entfernt
                subView.removeFromSuperview()
            }
        }
        
        loadData()
        configureView()
    }
    
    
    //
    //Methode um zu überprüfen ob die Eingabe gültig ist. Eine Eingabe muss hierbei folgende Kriterien erfüllen: genau 7 Zeichen, nur Zahlen und sie muss noch nicht gespeichert sein
    //(Methode: isUnique()). Sollte eine Bedingung nicht erfüllt sein, so wird dem Nutzer durch ein PopUp (=AlertView) Feedback gegeben.
    //
    func validInput(matrikelnummer : String) -> Bool{
        //Überprüfung der Eingabe: 7 Zeichen, nur Zahlen?
        if ((matrikelnummer.characters.count == 7) && (Int(matrikelnummer) != nil)){
            if (isUnique(matrikelnummer)) {
                return true
            }
            else {
//                showAlertViewWithTitle("Hinweis", message: "Diese Matrikelnummer ist bereits in der Liste vorhanden!")
                deleteSubviews()
                return false
            }
        } else {
            showAlertViewWithTitle("Hinweis", message: "Eine Matrikelnummer hat genau 7 Zahlen!")
            deleteSubviews()
            return false
        }
    }
    
    
    //
    //Methode um zu überprüfen, ob eine Matrikelnr. bereits im Speicher vorhanden ist. Sollte sie bereits gespeichert worden sein, dann wird dem Nutzer dies über ein AlertView
    //mitgeteilt und das UI wird zurückgesetzt.
    //
    func isUnique(matrikelnummer : String) -> Bool{
        for nummer in gespeicherte_Studenten{
            let student = nummer as! Student
            if (student.matrikelnummer == matrikelnummer){
                showAlertViewWithTitle("Hinweis", message: "Diese Matrikelnummer ist bereits in Liste vorhanden!")
                deleteSubviews()
                configureView()
                return false
            }
        }
        return true
    }
    
    //
    //Methode die bei Speicherproblemen aufgerufen wird um Aufräumarbeiten zu starten. Bisher traten keine Probleme auf, daher ist sie noch leer.
    //
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    //
    //Methode zum laden der gespeicherten Daten. Zunächst wird das gespeicherte_Studenten zur Sicherheit geleert. Danach werden alle persistent gespeicherten Datensätze in diesem Array
    //abgelegt.
    //
    func loadData(){
        
        //Sicherheitshalber das Array leeren
        gespeicherte_Studenten.removeAllObjects()
        
        
        //Referenz auf das in AppDelegate automatisch angelegte managedObjectContext (=persistenter Speicherort)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let moc = appDelegate.managedObjectContext
        
        // Fetch Request initialisieren mit der Entität "Student"
        let fetchRequest = NSFetchRequest(entityName: "Student")
        
        
        
        //Fetch Request starten. Es werden alle Entitäten mit dem Namen "Student" aus dem Speicher geladen. Danach wird mit Hilfe einer For-Schleife jedes Objekt als Student
        //im Array "gespeicherte_Studenten" abgelegt.
        do {
            if let results = try moc.executeFetchRequest(fetchRequest) as? [NSManagedObject]{
                self.gespeicherte_Studenten = []
                
                for result in results {
                    //Jeden gefundenen Stundenten aus dem Speicher in ein Array einfügen
                    let newStudent = result as! Student
                    self.gespeicherte_Studenten.addObject(newStudent)
                }
            }
        } catch {
            fatalError("Fehler beim FetchRequest ;/ \(error)")
        }
    }
    
    //
    //Methode, welche neue Datensätze (Matrikelnr. + Alias) persistent speichert. Die zu speichernde Matrikelnr. wird als Parameter übergeben und der Alias wird im Laufe der 
    //Ausführung der Methode über ein AlertView eingegeben.
    //
    func writeData(matrikelnummer : String){
        
        //Referenz auf AppDelegate um Zugriff auf managedObjectContext zu bekommen
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let moc = appDelegate.managedObjectContext
        
        //Erstellen der Entität um sie dann im moc speichern zu können
        let entityDescription = NSEntityDescription.entityForName("Student", inManagedObjectContext: moc)
        let newStudent = Student(entity: entityDescription!, insertIntoManagedObjectContext: moc)
        
        //dem Objekt die gewünschte Matrikelnummer zuweisen
        newStudent.matrikelnummer = matrikelnummer
        showAlertViewWithTextfield("Namensgebung", message: "Zugehöriger Name zur Matrikelnr.:", withText: true){(result) -> () in
            if (result.characters.count == 0){
                newStudent.name = matrikelnummer
            }
            else {
                newStudent.name = self.inputTextField!.text
            }
            print(newStudent)
            
            //Speichern
            do {
                try moc.save()
            } catch _ {
                fatalError("Fehler ist aufgetreten!")
            }
            self.showAlertViewWithTitle("Hinweis", message: "Matrikelnummer wurde erfolgreich gespeichert!")
            self.deleteSubviews()
        }

        

    }
    
    //
    //Methode um die Eingabe auf 7 Zeichen zu beschränken.
    //
    func textField(textField: UITextField,
        shouldChangeCharactersInRange range: NSRange,
        replacementString string: String)
        -> Bool
    {
        //So lange kein Zeichen hinzugefügt wird ignorieren wir die Eingabe
        if (string.characters.count == 0){
            return true
        }
        
        //Variable mit dem eingegebenen Text oder falls nil auf einen leeren String
        let currentText = textField.text ?? ""
        
        //prospectiveText lässt uns eine maximal länge für eine Eingabe festlegen
        let prospectiveText = (currentText as NSString).stringByReplacingCharactersInRange(range, withString: string)
        
        return prospectiveText.characters.count <= 7
        
    }
    
    //
    //Methode um das Keyboard zu schliessen (wird bei einem Tap aufgerufen)
    //
    func dismissKeyboard (){
        view.endEditing(true)
    }
    
    //
    //Methode um Statusmeldungen anzeigen zu können.
    //
    func showAlertViewWithTitle(title:String, message:String) {
        if #available(iOS 8.0, *){
            let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
            
            
            let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
            }
            
            alertController.addAction(OKAction)
            
            self.presentViewController(alertController, animated: true) {
            }

        }  else { //iOS 7
            let alert: UIAlertView = UIAlertView()
            alert.delegate = self
            
            alert.title = title
            alert.message = message
            alert.addButtonWithTitle("OK")
            
            alert.show()
            
            
        }
    }

    //
    //Methode um Statusmeldungen mit Textfeld anzeigen zu können. Unter iOS8 wird hier die Standardimplementierung verwendet. In iOS7 ist der "UIAlertController"
    //noch nicht verfügbar und daher muss "UIAlertView" genutzt werden. Sie bietet aber von Haus aus nicht die Möglichkeit an mit dem Programmfortschritt
    //zu warten bis das AlertView beendet wird. Daher wurde auf die Nutzung einer Bibliothek zurückgegriffen, welche diese Funktionalität für AlertViews realisiert
    //(siehe AlertViewWithCallbackDelegate.swift und AlertViewWithCallback.swift)
    //
    func showAlertViewWithTextfield(title: String, message: String, withText: Bool, completion: (result : String)-> ()){
        if #available(iOS 8.0, *){
            
            let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
            
            
            let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
                completion(result: self.inputTextField!.text!)
            }
            
            alertController.addAction(OKAction)
            
            alertController.addTextFieldWithConfigurationHandler{ textField -> Void in
                self.inputTextField = textField
                self.inputTextField!.text = textField.text
                print(self.inputTextField!.text)
            }
            
            self.presentViewController(alertController, animated: true) {
                // ...
            
            }
            
            //...
        }  else { //iOS 7
            let alert: UIAlertView = UIAlertView()
            alert.delegate = self
            
            alert.title = title
            alert.message = message
            alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
            self.inputTextField = alert.textFieldAtIndex(0)
            alert.addButtonWithTitle("Ok")
            alert.show()
            
            
            AlertViewWithCallback().show(alert) { alertView, buttonIndex in
                completion(result: alert.textFieldAtIndex(0)!.text!)
            }
            
        }
    }


}

This snippet took 0.06 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).