Hide buttons when textfield equals nil and show when not nil - ios

With my code the buttons are hiding when the viewcontroller is showing because the textfields are empty. The buttons should however show when the textfields are not empty anymore. The buttons are not showing with my code - what am I doing wrong?
let allInputValues = nameInput.text! + middleInput.text! + surnameInput.text!
if allInputValues == "" {
nextButton.hidden = true
finishButton.hidden = true
} else {
nextButton.hidden = false
finishButton.hidden = false
}
Hope you can help me

Set up your view controller as a textField delegate. Then use textFieldDidEndEditing() for each textField to run your check and either keep the button hidden or show the button.
class MyViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
nextButton.hidden = true
finishButton.hidden = true
nameInput.delegate = self
middleInput.delegate = self
surnameInput.delegate = self
}
func textFieldDidEndEditing(textField: UITextField) {
let allInputValues = nameInput.text! + middleInput.text! + surnameInput.text!
if allInputValues == "" {
nextButton.hidden = true
finishButton.hidden = true
} else {
nextButton.hidden = false
finishButton.hidden = false
}
}
}
Swift 3
class MyViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
nextButton.isHidden = true
finishButton.isHidden = true
nameInput.delegate = self
middleInput.delegate = self
surnameInput.delegate = self
}
func textFieldDidEndEditing(textField: UITextField) {
let allInputValues = nameInput.text! + middleInput.text! + surnameInput.text!
if allInputValues == "" {
nextButton.isHidden = true
finishButton.isHidden = true
} else {
nextButton.isHidden = false
finishButton.isHidden = false
}
}
}

You are only running the "if" once, at the start of the program. Place it into a loop that runs it each time the values change.

Related

how the disable the intermediate appearance of cursor on textFields in a otpscreen in swift 4

I have a OTP screen with 6 textfields and I need the cursor to not to move to the particular textField when I tap on the particular textField.
I already implemented the code to automatically move the cursor from one text field to another but if I touch on a particular text field (let's say 4th) the cursor is moving there.
Please help me with this problem and thanks in advance.
My OTP screen:
My Code:
func setDelegateAndTargetForAllTextFields() {
textField1.delegate = self
textField2.delegate = self
textField3.delegate = self
textField4.delegate = self
textField5.delegate = self
textField6.delegate = self
textField1.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
textField2.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
textField3.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
textField4.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
textField5.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
textField6.addTarget(self, action: #selector(textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
}
#IBAction func otpBtnTapped(_ sender: UIButton) {
if let text1 = textField1.text, let text2 = textField2.text, let text3 = textField3.text, let text4 = textField4.text,let text5 = textField5.text,let text6 = textField6.text {
if text1+text2+text3+text4+text5+text6 == ""{
showAlert(message: "Otp Cannot be empty!.")
textField1.text = ""
textField2.text = ""
textField3.text = ""
textField4.text = ""
textField5.text = ""
textField6.text = ""
textFieldIntermediateEditingDisabled()
}
else{
let setPinVC = self.storyboard?.instantiateViewController(withIdentifier: "pinVC") as! SetPinVC
self.navigationController?.pushViewController(setPinVC, animated: true)
}
}
}
#objc func textFieldDidChange(textField: UITextField) {
let text = textField.text
if text?.count == 1 {
switch textField{
case textField1:
//if textField2.isEnabled == false{
//textField2.isEnabled = true
//}
textField2.becomeFirstResponder()
case textField2:
//if textField3.isEnabled == false{
// textField3.isEnabled = true
// }
textField3.becomeFirstResponder()
case textField3:
//if textField4.isEnabled == false{
//textField4.isEnabled = true
//}
textField4.becomeFirstResponder()
case textField4:
//if textField5.isEnabled == false{
//textField5.isEnabled = true
//}
textField5.becomeFirstResponder()
case textField5:
// if textField6.isEnabled == false{
//textField6.isEnabled = true
//}
textField6.becomeFirstResponder()
default:
break
}
}
if text?.count == 0 {
switch textField {
case textField1:
//if textField1.isEnabled == false{
//textField1.isEnabled = true
//}
textField1.becomeFirstResponder()
case textField2:
// if textField1.isEnabled == false{
//textField1.isEnabled = true
//}
textField1.becomeFirstResponder()
case textField3:
//if textField2.isEnabled == false{
//textField2.isEnabled = true
//}
textField2.becomeFirstResponder()
case textField4:
//if textField3.isEnabled == false{
//textField3.isEnabled = true
//}
textField3.becomeFirstResponder()
case textField5:
//if textField4.isEnabled == false{
// textField4.isEnabled = true
//}
textField4.becomeFirstResponder()
case textField6:
//if textField5.isEnabled == false{
//textField5.isEnabled = true
//}
textField5.becomeFirstResponder()
default:
break
}
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let maxLength = 1
let currentString: NSString = textField.text! as NSString
let newString: NSString =
currentString.replacingCharacters(in: range, with: string) as NSString
return newString.length <= maxLength
}
You can use textFieldShouldBeginEditingto check and allow/discard textField to begin editing like this
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return true // edit the condition according to your requirement
}
Edit
If you want to check and allow if the previous textfield have value or not you can do something like this just put all the textfield into an array with there sequence from one to so on
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
let textfields : [UITextField] = [textfield1,textfield2,textfield3] // just to demonstrate
if (textField == textfield1) { return true }
var previousTextfield : UITextField?
for textfield in textfields{
if let pTextfiled = previousTextfield,let value = pTextfiled.text{
return value.isEmpty ? false : (textfield == textField)
}
previousTextfield = textfield
}
return false
}
Note: I didn't tested this code just added the answer according to the requirement let me know if this is what you wanted or something else.
Thanks.

Is there a better way to show and hide multiple textviews linked to segmented control than isHidden = true/false?

Beginner here and I've created a VC with 3 segmented controls with 3 segments each. Each segment selection shows a different textview. At any given time, 2 segmented controls show and so you have the option to switch between any of 6 textviews. There exist a total of 9 textviews.
The way I've written this now seems a little glitchy in the simulator and so I want to know of a better way to write this kind of repetitive code. I many lines of .isHidden = false and isHidden = true between all of selections of the 2/3 segmented controls that show at any time. Can anyone tell me how something like can be written in a safer way? If you want to just give a short example or tell me what to google, I appreciate that.
Here's what I have:
class ViewController: UIViewController {
#IBOutlet weak var segmentedControl: UISegmentedControl!
#IBOutlet weak var textSegmentedControl: UISegmentedControl!
#IBOutlet weak var translationSegmentedControl: UISegmentedControl!
#IBOutlet weak var firstLangText: UITextView!
#IBOutlet weak var secondLangText: UITextView!
#IBOutlet weak var thirdLangText: UITextView!
#IBOutlet weak var translationA: UITextView!
#IBOutlet weak var translationB: UITextView!
#IBOutlet weak var translationC: UITextView!
#IBOutlet weak var textInfo: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
style(control: segmentedControl)
segmentedControl.addTarget(self, action: #selector(updateMainSegmentedControl), for: .valueChanged)
textSegmentedControl.addTarget(self, action: #selector(updateTextSegmentedControl), for: .valueChanged)
translationSegmentedControl.addTarget(self, action: #selector(updateTranslationSegmentedControl), for: .valueChanged)
secondLangText.isHidden = true
thirdLangText.isHidden = true
translationSegmentedControl.isHidden = true
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = true
}
//Mark: Stye SegmentControls & underlineBar
func style(control: UISegmentedControl) {
control.backgroundColor = .clear
control.tintColor = .clear
control.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16), NSAttributedStringKey.foregroundColor: UIColor.secondaryColor], for: .normal)
control.setTitleTextAttributes([NSAttributedStringKey.font : UIFont.systemFont(ofSize: 16),NSAttributedStringKey.foregroundColor: UIColor.primaryColor], for: .selected)
}
#IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex {
case 0:
textSegmentedControl.isHidden = false
translationSegmentedControl.isHidden = true
translationUnderlineBar.isHidden = true
firstLangText.isHidden = false
translationA.isHidden = true
textInfo.isHidden = true
case 1:
textSegmentedControl.isHidden = true
translationSegmentedControl.isHidden = false
firstLangText.isHidden = true
translationA.isHidden = false
textInfo.isHidden = true
case 2:
textSegmentedControl.isHidden = true
translationSegmentedControl.isHidden = true
firstLangText.isHidden = true
textInfo.isHidden = false
default:
break;
}
}
#IBAction func selectTextLanguage(_ sender: UISegmentedControl) {
switch textSegmentedControl.selectedSegmentIndex {
case 0:
firstLangText.isHidden = false
secondLangText.isHidden = true
thirdLangText.isHidden = true
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = true
case 1:
firstLangText.isHidden = true
secondLangText.isHidden = false
thirdLangText.isHidden = true
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = true
case 2:
firstLangText.isHidden = true
secondLangText.isHidden = true
thirdLangText.isHidden = false
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = true
default:
break;
}
}
#IBAction func selectTranslationLanguage(_ sender: UISegmentedControl) {
switch translationSegmentedControl.selectedSegmentIndex {
case 0:
translationA.isHidden = false
translationB.isHidden = true
translationC.isHidden = true
firstLangText.isHidden = true
secondLangText.isHidden = true
thirdLangText.isHidden = true
case 1:
translationA.isHidden = true
translationB.isHidden = false
translationC.isHidden = true
firstLangText.isHidden = true
secondLangText.isHidden = true
thirdLangText.isHidden = true
case 2:
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = false
firstLangText.isHidden = true
secondLangText.isHidden = true
thirdLangText.isHidden = true
default:
break;
}
}
First you need to extract the behavior which is common from the switch case so that you can remove some duplicate.
#IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex {
case 0:
translationUnderlineBar.isHidden = true
textInfo.isHidden = true
firstLangText.isHidden = false
translationA.isHidden = true
textSegmentedControl.isHidden = false
translationSegmentedControl.isHidden = true
case 1:
textInfo.isHidden = true
firstLangText.isHidden = true
translationA.isHidden = false
textSegmentedControl.isHidden = true
translationSegmentedControl.isHidden = false
case 2:
textInfo.isHidden = false
firstLangText.isHidden = true
textSegmentedControl.isHidden = true
translationSegmentedControl.isHidden = true
default:
break;
}
}
#IBAction func selectTextLanguage(_ sender: UISegmentedControl) {
switch textSegmentedControl.selectedSegmentIndex {
case 0:
showLanaguage(which: firstLangText)
case 1:
showLanaguage(which: secondLangText)
case 2:
showLanaguage(which: thirdLangText)
default:
break;
}
translationA.isHidden = true
translationB.isHidden = true
translationC.isHidden = true
}
func showLanaguage(which: UITextView){
[firstLangText,secondLangText,thirdLangText].forEach({
$0?.isHidden = $0 != which
})
}
func showTranslation(which: UITextView){
[translationA,translationB,translationC].forEach({
$0?.isHidden = $0 != which
})
}
#IBAction func selectTranslationLanguage(_ sender: UISegmentedControl) {
switch translationSegmentedControl.selectedSegmentIndex {
case 0:
showTranslation(which: translationA)
case 1:
showTranslation(which: translationB)
case 2:
showTranslation(which: translationC)
default:
break;
}
firstLangText.isHidden = true
secondLangText.isHidden = true
thirdLangText.isHidden = true
}
You could set them all to a default value before the switch and then just update the different ones in the case. This works especially well in your third method where the default state is true for most views.
#IBAction func selectTranslationLanguage(_ sender: UISegmentedControl)
{
[translationA, translationB, translationC, firstLangText,
secondLangText, thirdLangText].forEach { $0.isHidden = true }
switch translationSegmentedControl.selectedSegmentIndex
{
case 0: translationA.isHidden = false
case 1: translationB.isHidden = false
case 2: translationC.isHidden = false
default: break
}
}
You can reuse your text views if they have the same position. If they are meant to be different, you can group them using outlet collections. So you will have
#IBOutlet weak var langTextViews: [UITextView]!
Instead of:
#IBOutlet weak var firstLangText: UITextView!
#IBOutlet weak var secondLangText: UITextView!
#IBOutlet weak var thirdLangText: UITextView!
It will make your code more organized and readable. You can optimize the textView hiding/showing part. For example, textOrTranslationChange mehtod will look something like this:
#IBAction func textOrTranslationChange(_ sender: UISegmentedControl) {
textSegmentedControl.isHidden = (segmentedControl.selectedSegmentIndex != 0)
langTextViews[0].isHidden = (segmentedControl.selectedSegmentIndex != 0)
translationSegmentedControl.isHidden = (segmentedControl.selectedSegmentIndex != 1)
textInfo.isHidden = (segmentedControl.selectedSegmentIndex != 2)
etc...
}
An elegant solution is to use the beauty of UISegmentedControl. Swift Dictionaries and the tag property.
You can utilize a single UITextView by setting the initial tag of the segmented control and then referencing the tag and selectedIndex to determine which field or value to change. You can then easily store the values in a Dictionary without the need of complex switch statements.
Here is a minimal, repeatable example. you should implement your own methods of handling values after input such as validation.
import Foundation
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
// Properties
var activeSegment: UISegmentedControl?
var activeIndex: Int?
var values:[String: String] = [:]
lazy var segmentedController: UISegmentedControl = {
let seg = UISegmentedControl(items: ["Name", "Age", "Language"])
seg.translatesAutoresizingMaskIntoConstraints = false
seg.tag = 0
seg.addTarget(self, action: #selector(segmentedControllerValueChanged(sender:)), for: .valueChanged)
return seg
}()
lazy var secondSegmentedController: UISegmentedControl = {
let seg = UISegmentedControl(items: ["Type", "Kind", "Thing"])
seg.translatesAutoresizingMaskIntoConstraints = false
seg.tag = 1
seg.addTarget(self, action: #selector(segmentedControllerValueChanged(sender:)), for: .valueChanged)
return seg
}()
let textField: UITextField = {
let tf = UITextField(frame: CGRect.zero)
tf.translatesAutoresizingMaskIntoConstraints = false
tf.placeholder = "Select Field"
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
self.layoutSubviews()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
func layoutSubviews() {
let guide = self.view.safeAreaLayoutGuide
let spacing:CGFloat = 12.0
self.view.addSubview(segmentedController)
self.view.addSubview(secondSegmentedController)
self.view.addSubview(textField)
segmentedController.widthAnchor.constraint(equalTo: guide.widthAnchor).isActive = true
segmentedController.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
segmentedController.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -spacing).isActive = true
segmentedController.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true
secondSegmentedController.widthAnchor.constraint(equalTo: guide.widthAnchor).isActive = true
secondSegmentedController.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
secondSegmentedController.bottomAnchor.constraint(equalTo: segmentedController.topAnchor, constant: -spacing).isActive = true
secondSegmentedController.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true
textField.centerXAnchor.constraint(equalTo: guide.centerXAnchor).isActive = true
textField.centerYAnchor.constraint(equalTo: guide.centerYAnchor).isActive = true
textField.heightAnchor.constraint(equalToConstant: 55.0).isActive = true
textField.widthAnchor.constraint(equalTo: guide.widthAnchor, constant: -spacing*2).isActive = true
}
#objc func segmentedControllerValueChanged(sender: UISegmentedControl) {
// Clear all other segments
let segmentedcontrols = [segmentedController, secondSegmentedController]
segmentedcontrols.forEach { (control) in
if (control.tag != sender.tag) {
control.selectedSegmentIndex = -1
}
}
// Safely get the title for the index
guard let titleForIndex = sender.titleForSegment(at: sender.selectedSegmentIndex) else {
self.textField.placeholder = "Select Field"
return
}
// Set the active fields.
self.textField.text = nil
self.textField.placeholder = "Input " + titleForIndex
self.activeSegment = sender
self.activeIndex = sender.selectedSegmentIndex
// Handle Text Input with your own methods / switch statements
print("Value did change to: \( sender.selectedSegmentIndex) with tag \(sender.tag)" )
print("values: \(values)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: - Text Field Delegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Safely get the title for the index
guard let segment = activeSegment, let index = activeIndex, let activeSegmentTitle = segment.titleForSegment(at: index) else {
return false
}
guard let text = textField.text else {
return false
}
values[activeSegmentTitle] = text
textField.resignFirstResponder()
return true
}
}

Incorrect height of tableview cell XIB in UITableView for first time?

I am having hard time resolving one issue. I have a tableview which has many prototype cells. One of them i am using a tagview to show multiple tags selected. So i have used a XIB file which has a TAGVIEW as subview of it & I have used that XIB in tableview cell. Now when i first load the tableview and scroll down then height of cell is large but when i scroll down and up then it's fits in the size of tags. I have tried below solutions for the but not of them worked.
I tried solutions:
1.cell.layoutIfNeeded before return cell.
2.cell.layoutSubView
3.cell.tagView.layoutIfNeeded
4.cell.setNeedsLayout()
5.Relaod tableview in ViewDidAppear
6.In tagViewCellXIB, in AwakeForNib method added self.layoutIfNeeded.
7.In tagViewCellXIB,Override didMoveToParent() & added self.layoutIfNeeded.
I have given estimated row height already.
Here is tagViewCell Class
class TagViewCell: UITableViewCell {
#IBOutlet weak var tagView: TagListView!
#IBOutlet weak var textfield: UITextField!
#IBOutlet weak var titleLbl: UILabel!
#IBOutlet weak var heightTagViewConstraint : NSLayoutConstraint!
#IBOutlet weak var lblValidation: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.layoutIfNeeded()
// Initialization code
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
self.layoutIfNeeded()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
self.heightTagViewConstraint.constant = 35
}
func configureView(type: TagCellType){
switch type {
case .Language:
setupLanguageCell()
titleLbl.text = "Language"
textfield.isHidden = true
if UserData.userData.language.count == 0{
tagView.isHidden = true
textfield.isHidden = false
textfield.placeholder = "What languages do you speak?"
}
break
default:
textfield.isHidden = true
setupTagCell(tagType: type)
if type == .preferArea {
seUpPreffredAreaValidation()
titleLbl.text = "Preferred areas"
if UserData.userData.preferAreaArr.count == 0{
tagView.isHidden = true
textfield.isHidden = false
textfield.placeholder = "What areas do you prefer?"
}
}
else if type == .City{
titleLbl.text = "Preferred cities"
if UserData.userData.cities.count == 0{
tagView.isHidden = true
textfield.isHidden = false
textfield.placeholder = "What city do you prefer? (Optional)"
}
}else{
titleLbl.text = "Preferred countries"
if UserData.userData.country.count == 0{
tagView.isHidden = true
textfield.isHidden = false
textfield.placeholder = "What country do you prefer? (Optional)"
}
}
break
}
}
/// Set up tag view
func setupLanguageCell() {
tagView.removeAllTags()
tagView.tag = 1003 // For Language field
for (index, elememt) in UserData.userData.language.enumerated() {
print(index)
if let langDict = elememt as? NSDictionary{
tagView.isHidden = false
let languageTagView = tagView.addTag(langDict.value(forKey: "lang_name") as! String)
languageTagView.tagBackgroundColor = UIColor.clear
languageTagView.textColor = .black
languageTagView.textFont = UIFont.systemFont(ofSize: 17)
languageTagView.paddingX = -1
languageTagView.isUserInteractionEnabled = false
let levelTagView = tagView.addTag(Constants.languageLevel[langDict.value(forKey: "level") as! Int])
levelTagView.frame = CGRect(x: levelTagView.frame.origin.x, y: (languageTagView.frame.height / 2) - (levelTagView.frame.height / 2) + 2, width: levelTagView.frame.width, height: levelTagView.frame.height)
levelTagView.layoutIfNeeded()
levelTagView.layoutSubviews()
levelTagView.tagBackgroundColor = UIColor().textOrange()
levelTagView.textFont = UIFont.systemFont(ofSize: 10)
levelTagView.cornerRadius = 6
print("pading yyyyyy \(String(describing: tagView.rowViews.last?.frame.minY))")
if UserData.userData.language.count == index+1{
if (tagView.rowViews.last?.frame.minY)! == 48{
levelTagView.frame.origin.y = (languageTagView.frame.height / 2) - (levelTagView.frame.height / 2) + 8
}
}
}
}
if UserData.userData.language.count == 0 {
self.lblValidation.isHidden = false
} else {
self.lblValidation.isHidden = true
}
}
func seUpPreffredAreaValidation() {
if UserData.userData.preferAreaArr.count == 0 {
self.lblValidation.isHidden = false
} else {
self.lblValidation.isHidden = true
}
}
/// setup cell for country and cities
///
/// - Parameter tagType: type of cell country or cities
func setupTagCell(tagType:TagCellType) {
tagView.removeAllTags()
var tagArray:[String] = []
tagArray = UserData.userData.country
tagView.tag = 1001 // For countries field
if tagType == .City {
tagArray = []
tagArray = UserData.userData.cities
tagView.tag = 1002 // For city field
}
if tagType == .preferArea {
tagArray = []
tagArray = UserData.userData.preferAreaArr
tagView.tag = 1003
}
var tagValue = ""
for (_, elememt) in tagArray.enumerated() {
tagView.isHidden = false
print(elememt)
if elememt.characters.count > 17 {
let index = elememt.index(elememt.startIndex, offsetBy: 16)
tagValue = elememt.substring(to: index) + ".."
}else{
tagValue = elememt
}
let levelTagView = tagView.addTag(tagValue)
levelTagView.tagBackgroundColor = UIColor().textOrange()
tagView.textFont = UIFont.systemFont(ofSize: 17)
levelTagView.cornerRadius = 8
levelTagView.enableRemoveButton = false
levelTagView.paddingX = 6
levelTagView.paddingY = 3
}
}
}
For cellForRowAtIndexPath below code is used
let cell = self.tableView.dequeueReusableCell(withIdentifier: "tagcell", for: indexPath) as! TagViewCell
cell.configureView(type: .City)
cell.tagView.delegate = self
if UserData.userData.cities.count >= 0 && UserData.userData.cities.count <= 3 {
cell.heightTagViewConstraint.constant = 25.7
}
else if let height = cell.tagView.subviews.last?.frame.maxY {
cell.heightTagViewConstraint.constant = height + 10
}
return cell
Override layoutSubviews in your TagViewCell class like bellow
class TagViewCell: UITableViewCell {
override func layoutSubviews() {
//Set the frame of tagView here
//self.tagView.frame =
}
}
and call cell.layoutIfNeeded while returning cell. If you still get any problem please comment. we are here to help you.

UIFocusGuide UITableView and UIButton

I am having a hard time creating a UIFocusGuide that will jump from the UITableView to a UIButton. Here is the debugger context screenshot:
And here is the implementation:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
// add the focus guide
self.view.addLayoutGuide(focusGuide)
// add the anchors
self.focusGuide.leftAnchor.constraintEqualToAnchor(self.button.leftAnchor).active = true
self.focusGuide.topAnchor.constraintEqualToAnchor(self.tableView.topAnchor).active = true
self.focusGuide.widthAnchor.constraintEqualToAnchor(self.button.widthAnchor).active = true
self.focusGuide.heightAnchor.constraintEqualToAnchor(self.tableView.heightAnchor).active = true
}
override func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
guard let nextFocusedView = context.nextFocusedView else { return }
switch nextFocusedView {
case self.button:
self.focusGuide.preferredFocusedView = self.button
case self.tableView:
self.focusGuide.preferredFocusedView = self.tableView
default:
self.focusGuide.preferredFocusedView = nil
}
}
The didUpdateFocusInContext function is never getting called when I am at the middle item of the UITableView or the end of the UITableView.
Add the focus guide to the button not self.view. You don't need override didUpdateFocusInContext For example:
var focusGuide = UIFocusGuide()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
// add the focus guide
self.button.addLayoutGuide(focusGuide)
// add the anchors
self.focusGuide.leftAnchor.constraintEqualToAnchor(self.button.leftAnchor).active = true
self.focusGuide.topAnchor.constraintEqualToAnchor(self.tableView.topAnchor).active = true
self.focusGuide.widthAnchor.constraintEqualToAnchor(self.button.widthAnchor).active = true
self.focusGuide.heightAnchor.constraintEqualToAnchor(self.tableView.heightAnchor).active = true
}

Swift - Hide & Show Object

When I press the button hide to my text, after I press button to show my text. Where is my fault? My English very bad, sorry...
#IBOutlet weak var myHiddenText: UILabel!
#IBAction func showBtn(sender: AnyObject) {
myHiddenText.hidden = true
if myHiddenText.hidden == true {
myHiddenText.hidden = false
}
if myHiddenText.hidden == false {
myHiddenText.hidden = true
}
}
If you want the button to toggle the hidden property of the label, simply do this:
#IBAction func showBtn(sender: AnyObject) {
myHiddenText.hidden = !myHiddenText.hidden
}
Your main issue was this line:
myHiddenText.hidden = true
This was hiding the label every time then your if statement would always be true and show your label. Then the second if statement would be true and hide the label again.
So another option to fix your code would be:
#IBAction func showBtn(sender: AnyObject) {
if myHiddenText.hidden == true {
myHiddenText.hidden = false
} else {
myHiddenText.hidden = true
}
}
I know this may not help you but it may help someone else. If you want to hide multiple objects you could do this.
Step 1: Reference all the objects you want to hide with #IBOutlet
Step 2: Declare this variable
var buttons_are_hidden: Bool = false
Step 3: Put this code where you need it
if self.buttons_are_hidden == true {
self.first_object.isHidden = true
self.second_object.isHidden = true
self.third_object.isHidden = true
self.buttons_are_hidden = true
} else {
self.first_object.isHidden = true
self.second_object.isHidden = true
self.third_object.isHidden = true
self.buttons_are_hidden = true
}
Hope it helps someone!
With UIKitPlus library you can do it simply like this
class MyViewController: ViewController {
#State var hiddency = false
override func buildUI() {
super.buildUI()
body {
VStack {
View().height(10).background(.red).hidden($hiddency)
View().height(10).background(.green).hidden($hiddency)
View().height(10).background(.blue).hidden($hiddency)
Button("toggle").onTapGesture {
self.hiddency.toggle()
}
}
}
}
}
Take a look at it, it works since iOS9+ and have LivePreview.

Resources