2017-03-08 1 views
0

Je suis très novice dans la programmation d'applications iOS (j'ai commencé à apprendre il y a moins d'une semaine!), Donc je suis sûre que ce que je demande est très évident! Donc je travaille sur une demande pour mon poste d'étude de travail et ne peux pas pour la vie de moi comprendre ce que je fais mal. Fondamentalement, tout ce que je veux faire est de vérifier que chaque champ est rempli avant de permettre à l'utilisateur de continuer. J'ai fait une chose similaire dans un autre contrôleur de vue pour vérifier si ce qui était entré est égal au mot de passe que j'ai défini pour le programme (je suis sûr qu'il y a une meilleure façon de le faire, mais parce que première application, je ne suis pas trop inquiet.J'ai une année entière à polir!)XCode8/Swift ne me laisse pas définir le texte d'un textField égal à une chaîne?

Voici le code pour cela (si vous avez des suggestions qui peuvent l'améliorer, n'hésitez pas, mais pour la plupart, Je viens d'essayer de comprendre pourquoi cela a fonctionné et l'autre code n'est pas)

@IBAction func enterPassword(_ sender: Any) { 

    pw = password.text! 
    let message = "Incorrect Password" 

    if(pw == "RISE") 
    { 
     performSegue(withIdentifier: "ToMenu", sender: self) 
    } 
    else { 
     incorrect.text = message 
    } 
} 

s'il vous plaît noter que la variable « pw » est une variable globale et est déclarée en dehors de la classe. Mot de passe et incorrect sont les deux étiquettes précédemment déclarées.

Voici le code qui est en question. Je ne comprends pas pourquoi j'ai une erreur pour ça. c'est "thread 1: exc_bad_instruction". Honnêtement, je ne suis même pas sûr de ce que cette erreur signifie, donc si vous savez ce que cela signifie, s'il vous plaît éclairer moi! J'ai inclus tout le code pour le viewController avec le problème.

import UIKit 


var studName = " " 
class CreateViewController: UIViewController { 

@IBOutlet weak var name: UITextField! 
@IBOutlet weak var ID: UITextField! 
@IBOutlet weak var YR: UITextField! 
@IBOutlet weak var test: UILabel! 


@IBAction func endCreate(_ sender: Any) { 
    studName = name.text! 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Do any additional setup after loading the view. 
} 

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

/* 
// MARK: - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    // Get the new view controller using segue.destinationViewController. 
    // Pass the selected object to the new view controller. 
} 
*/ 
} 

Qu'est-ce que je fais mal ici? Je suis vraiment incertain et confus. Je suis assez doué pour coder en Java et en C++ donc je ne m'attendais jamais à avoir des problèmes d'apprentissage mais c'est totalement différent et ça prend beaucoup plus de temps que prévu (ça m'a pris environ une semaine pour apprendre C# ...).

Merci pour toute aide!

EDIT: (je dois 10 points de réputation pour poster plus de deux liens, alors j'ai supprimé l'erreur lol Je suppose que je vais répondre à certaines questions ou quelque chose.)

Click here to see StoryBoard

Click here to see Connection to NAME (note I reconnected it and used all caps, error is still an issue)

S'il y a d'autres informations qui peuvent vous aider à comprendre, s'il vous plaît faites le moi savoir! Merci!

+0

Pouvez-vous poster une capture d'écran de l'erreur que vous rencontrez et où cela se passe-t-il? –

+0

Sans voir plus, il semble que votre nom de sortie n'est pas connecté. – BJHStudios

+0

La question pourrait être plus courte pour attirer plus d'attention. De toute façon, dans quelle ligne vous obtenez une erreur? –

Répondre

1

Je suppose ici que vous rencontrez l'accident sur cette ligne

studName = name.text! 

? (Si vous ne pourriez pas inclure la s'il vous plaît trace de la pile pour indiquer où vous avez trouvé un problème?)

On dirait que ce soit name est nil ou text est nil qui sont tous deux être la force déballa ici. Donc, soit vous n'avez pas correctement connecté ce champ de texte dans le constructeur de l'interface, soit il n'y a tout simplement pas de texte.

Ma règle générale est (et je suis sûr que les gens seront en désaccord avec cela):

NE JAMAIS utiliser !

Une telle règle simple :)

Je raisonne ce que le déploiement de force d'une variable facultative n'est jamais (très, très rarement) requis et implique une supposition d'une valeur qui était clairement destinée à être nulle (sinon, elle ne serait pas facultative). En règle générale, si vous utilisez un ! sur l'une de vos propres variables, pensez à refactoriser la variable pour qu'elle ne soit pas facultative, sinon faites un usage intensif des instructions optionnelles de liaison et/ou de garde pour éviter de forcer les choses.

(Mon problème principal est de créer des variables d'instance qui requièrent self comme paramètre pour l'initialisation.) Où la variable d'instance est implicitement déballée optionnelle, mais est immédiatement définie après l'appel de l'initialiseur de super, et plus jamais

Aussi, bien que cela fonctionne et est un code valide, il n'est pas typique d'utiliser des variables globales pour des choses comme studName, cela devrait être une variable d'instance dans votre contrôleur.

N'hésitez pas à crier si vous avez d'autres questions à ce sujet (ou quoi que ce soit sur iOS/swift). Si vous venez de commencer, je ne peux pas recommander http://web.stanford.edu/class/cs193p assez fortement! Un aperçu complet de toutes les technologies iOS de base et des modèles de conception.

EDIT pour commentaires

Dans ce cas, vous pouvez éviter d'utiliser cette ! en rendant votre variable facultative, vous pouvez déclarer studName en utilisant

var studName: String? = " " 

ce fait une variable facultative qui vous permettra pour lui attribuer une valeur nulle.

Si vous êtes sûr que vous ne voulez pas qu'il soit nul, vous pouvez aussi faire votre affectation en tant que

studName = name.text ?? " " 

Cela vérifiera la valeur de name.text et si elle ne nil céder à studName, sinon il affectera la valeur sur la droite " ". Cela vous permet essentiellement de fournir une valeur par défaut pour une affectation qui n'est pas facultative. Il est un raccourci pour:

if let text = name.text { 
    studName = text 
} else { 
    studName = " " 
} 
+0

Oui, c'est là que j'ai le problème. mon application plante, peu importe ce que mon champ de texte, le nom a dedans. quelqu'un d'autre a dit que ce n'était pas connecté, je vais essayer de le faire à nouveau. Mais pendant que je déconne, comment ne pas utiliser "!"? J'aimerais ne pas l'utiliser, mais je reçois une erreur si je ne le fais pas. –

+0

La reconnexion n'a pas fonctionné. Y at-il autre chose de mon programme qui peut vous aider à comprendre pourquoi l'application plante sur cette ligne? –

+0

@AmberRebeccaHowe Hmmm, pourriez-vous ajouter un 'print (studName)', 'print (name)', et 'print (name.text)' au-dessus de la ligne qui plante, cela devrait faire la lumière? –

-1

Tout d'abord,

Prenez une sortie pour le TextField comme indiqué ci-dessous

// MARK:- IBOutlets 
    @IBOutlet var passwordTextField: UITextField!` 

Prenez un bouton & assigner IBAction le bouton "passwordCheck" dans ce Cas. Vous pouvez comparer TextField texte à chaîne comme indiqué ci-dessous

// MARK:- IBActions 
@IBAction func passwordCheck(_ sender: Any) { 
    if passwordTextField.text == "RISE" { 
     print("perform Segue") 
    } else { 
     print("Do nothing") 
    } 
} 

Permettez-moi de savoir si vous avez des doutes ...

+0

Le code de mot de passe fonctionne, en fait! Je prendrai vos suggestions en considération. Y at-il quelque chose avec la deuxième partie du code que j'ai ajouté que vous pouvez m'aider? la ligne "studName = name.text!" fait planter mon application. –

+0

@AmberRebeccaHowe À ma connaissance, il n'y a aucun problème dans la section. Pour s'assurer que j'ai fait exactement ce que vous avez fait, cela a fonctionné pour moi. Voir le lien ci-dessous. –

+0

[IMG] http: //i65.tinypic.com/20j65hj.jpg [/ IMG] –

0

Bon début. Voici comment je l'écrirais:

@IBAction func enterPassword(_ sender: Any) { 

     //Make sure we trim off any white space or new lines and then optionally bind the text in the text field. 
     guard let passwordText = self.password.text?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) else { 
      self.incorrect.text = "Please enter a password." 
      return 
     } 
     //Make sure text is not a blank string eg: "" 
     guard !passwordText.isEmpty else { 
      self.incorrect.text = "Please enter a password." 
      return 
     } 
     //Make sure it is the password we want. 
     guard passwordText == "ThePassword" else { 
      self.incorrect.text = "Not the correct password." 
      return 
     } 

     //Success! Do other stuff here. Like perform a segue. 

} 

Et juste pour faire bonne mesure et un peu de plaisir. Voici une excellente extension sur UITextField pour fournir une belle petite animation si quelque chose n'est pas valide.

extension UITextField { 
    func shake(times T: Int, distance D: CGFloat) { 
     UIView.animate(withDuration: 0.06, animations: { 
     self.transform = CGAffineTransform(translationX: D, y: 0) 
     }) { (didComplete) in 
     UIView.animate(withDuration: 0.06, animations: { 
      self.transform = CGAffineTransform.identity 
     }, completion: { (didComplete) in 

      guard T > 0 else { 
       return 
      } 
      self.shake(times: T - 1, distance: D) 
     }) 
     } 
    } 
} 

George Green est droite. Le déballage forcé dans Swift est considéré comme une odeur de code. Toujours lier facultativement une valeur facultative. Fait un code un peu plus verbeux mais garde tout en sécurité.

+0

Le déballage n'est pas une odeur de code mais une opération légitime. Vous devez juste décider correctement quand vous pouvez forcer le déballage et reconnaître le crash quand cela arrive. – Sulthan

+0

@Sulthan Pas selon le premier [article dans le premier résultat de recherche Google] (https://cocoacasts.com/five-signs-of-code-smell-in-swift/) pour "Swift code odeurs" –

+0

Le blog le message ne dit pas * ne jamais utiliser le déballage forcé *. Il dit * utiliser avec prudence *. L'opérateur existe dans Swift pour une raison. – Sulthan

0

Et voilà ... là, je vois le problème. J'ai enlevé Outlet au TextField et immédiatement j'ai vu cette erreur. See error here

Veuillez vous assurer que vous connectez le IBOutlet correctement et il fonctionne parfaitement comme indiqué ci-dessous. See how it works

Espérons que cela vous aide.

+0

Peut-être que je ne comprends pas comment le connecter ...? Je tiens le contrôle et le traîne sur le code et sélectionne la sortie. J'ai le sentiment qu'il pourrait y avoir quelque chose d'autre avec ça ... –

+0

@AmberRebeccaHowe pouvez-vous m'envoyer la capture d'écran de la connexion TextField IBOutlet (aussi bien sur Textfield que sur Code). –