-
Notifications
You must be signed in to change notification settings - Fork 132
Project #141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Project #141
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent job on this Sprint Challenge, Cora! I would say the main thing that you need to focus on going forward is breaking code up into smaller single purpose functions, though I know it can be hard in a time-limited setting such as a Sprint Challenge. Focus on that though as you do your module projects so that it will come more naturally during your challenges as well. Overall though, your control works well and looks great. Keep up the great work!
func checkStrength(_ password: String) { | ||
let checker = UITextChecker() | ||
let range = NSRange(location: 0, length: password.count) | ||
let wordRange = checker.rangeOfMisspelledWord(in: password, range: range, startingAt: 0, wrap: false, language: "en") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job figuring out that you could use the rangeOfMisspelledWord to find valid words!
func checkStrength(_ password: String) { | ||
let checker = UITextChecker() | ||
let range = NSRange(location: 0, length: password.count) | ||
let wordRange = checker.rangeOfMisspelledWord(in: password, range: range, startingAt: 0, wrap: false, language: "en") | ||
switch password.count { | ||
case 10...19: | ||
oldStrength = strength | ||
if wordRange.location == NSNotFound { | ||
strength = .weak | ||
mediumView.backgroundColor = unusedColor | ||
} else { | ||
strength = .medium | ||
mediumView.backgroundColor = mediumColor | ||
} | ||
strongView.backgroundColor = unusedColor | ||
strengthDescriptionLabel.text = strength.rawValue | ||
if oldStrength != strength { | ||
mediumView.performFlare() | ||
} | ||
case 20...: | ||
oldStrength = strength | ||
if wordRange.location == NSNotFound { | ||
strength = .medium | ||
strongView.backgroundColor = unusedColor | ||
} else { | ||
strength = .strong | ||
strongView.backgroundColor = strongColor | ||
} | ||
mediumView.backgroundColor = mediumColor | ||
strengthDescriptionLabel.text = strength.rawValue | ||
if oldStrength != strength { | ||
strongView.performFlare() | ||
} | ||
default: | ||
oldStrength = strength | ||
strength = .weak | ||
mediumView.backgroundColor = unusedColor | ||
strongView.backgroundColor = unusedColor | ||
strengthDescriptionLabel.text = strength.rawValue | ||
if oldStrength != strength { | ||
weakView.performFlare() | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is a bit lengthy, but more importantly it not only checks the strength but also updates the UI. Try to keep your functions as focused and single purposed as possible. When we get into testing, this will make them easier to test as well.
isUserInteractionEnabled = true | ||
|
||
backgroundColor = bgColor | ||
|
||
titleLabel.textColor = labelTextColor | ||
titleLabel.font = labelFont | ||
titleLabel.text = "Enter Password" | ||
addSubview(titleLabel) | ||
titleLabel.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
NSLayoutConstraint.activate([ | ||
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: standardMargin), | ||
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: standardMargin), | ||
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -standardMargin)]) | ||
|
||
textFieldContainer.layer.cornerRadius = 8 | ||
textFieldContainer.layer.borderColor = textFieldBorderColor.cgColor | ||
textFieldContainer.layer.borderWidth = 3 | ||
addSubview(textFieldContainer) | ||
textFieldContainer.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
NSLayoutConstraint.activate([ | ||
textFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: standardMargin), | ||
textFieldContainer.leadingAnchor.constraint(equalTo: leadingAnchor, constant: standardMargin), | ||
textFieldContainer.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -standardMargin), | ||
textFieldContainer.heightAnchor.constraint(equalToConstant: textFieldContainerHeight)]) | ||
|
||
showHideButton.contentMode = .scaleAspectFit | ||
showHideButton.setImage(UIImage(named: "eyes-open"), for: .normal) | ||
showHideButton.addTarget(self, action: #selector(showHide), for: .touchUpInside) | ||
addSubview(showHideButton) | ||
showHideButton.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
NSLayoutConstraint.activate([ | ||
showHideButton.centerYAnchor.constraint(equalTo: textFieldContainer.centerYAnchor), | ||
showHideButton.trailingAnchor.constraint(equalTo: textFieldContainer.trailingAnchor, constant: -textFieldMargin)]) | ||
|
||
textField.placeholder = "password" | ||
textField.autocapitalizationType = .none | ||
textField.autocorrectionType = .no | ||
textField.delegate = self | ||
addSubview(textField) | ||
textField.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
NSLayoutConstraint.activate([ | ||
textField.centerYAnchor.constraint(equalTo: textFieldContainer.centerYAnchor), | ||
textField.leadingAnchor.constraint(equalTo: textFieldContainer.leadingAnchor, constant: textFieldMargin), | ||
textField.widthAnchor.constraint(equalToConstant: 250)]) | ||
|
||
weakView.backgroundColor = weakColor | ||
weakView.layer.cornerRadius = 2 | ||
weakView.frame = CGRect(x: standardMargin, y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(weakView) | ||
|
||
mediumView.backgroundColor = unusedColor | ||
mediumView.layer.cornerRadius = 2 | ||
mediumView.frame = CGRect(x: standardMargin + 52, y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(mediumView) | ||
|
||
strongView.backgroundColor = unusedColor | ||
strongView.layer.cornerRadius = 2 | ||
strongView.frame = CGRect(x: standardMargin + (2 * 52), y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(strongView) | ||
|
||
strengthDescriptionLabel.textColor = labelTextColor | ||
strengthDescriptionLabel.font = labelFont | ||
strengthDescriptionLabel.text = strength.rawValue | ||
addSubview(strengthDescriptionLabel) | ||
strengthDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
NSLayoutConstraint.activate([ | ||
strengthDescriptionLabel.centerYAnchor.constraint(equalTo: strongView.centerYAnchor), | ||
strengthDescriptionLabel.leadingAnchor.constraint(equalTo: strongView.trailingAnchor, constant: standardMargin)]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try to break out your setup into sub-functions where appropriate.
return true | ||
} | ||
|
||
func checkStrength(_ password: String) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to mark functions as private that don't need to be accessed from external classes.
weakView.backgroundColor = weakColor | ||
weakView.layer.cornerRadius = 2 | ||
weakView.frame = CGRect(x: standardMargin, y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(weakView) | ||
|
||
mediumView.backgroundColor = unusedColor | ||
mediumView.layer.cornerRadius = 2 | ||
mediumView.frame = CGRect(x: standardMargin + 52, y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(mediumView) | ||
|
||
strongView.backgroundColor = unusedColor | ||
strongView.layer.cornerRadius = 2 | ||
strongView.frame = CGRect(x: standardMargin + (2 * 52), y: self.bounds.size.height - 16, width: 50, height: 5) | ||
addSubview(strongView) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would try not to mix in frame based layout with auto layout in this fashion. If the user changes the height of the control, the layout breaks. Again, I would suggest having controls set up in a way that fully defines their height if reasonable, just like switches and sliders and such do. That would mean that your top-most view is constrained to the top of the control (as you currently have) and the bottom-most view is constrained to the bottom of the control. Stack views would make this setup much easier, as you could just pin your main stack view to each edge of the control.
@swift-student