Clear placeholder text from storyboard or XIB outlets - ios

In my XIB file and storyboards I have some UILabel's with placeholder text that I would like to clear out before the view loads.
Is there some function provided by the SDK for this purpose?
What is best practice for doing this?

You need to connect each UILabel to correspond IBOutlet variable in your code and change the text of it on early stage of view's lifecycle.
#IBOutlet weak var someLabel: UILabel! // connected in xib
override func viewDidLoad() {
someLabel.text = ""
}

Related

View Controller loses connection to constraints in IBOutlets when switching tabs in UITabView

OK, so here's the relevant bit of my code:
class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var questionView: QuestionView!
#IBOutlet weak var answerView: AnswerView!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint! // Active at start, attaches tableView.topAnchor to questionView.bottomAnchor
#IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint! // Inactive at start, attaches tableView.topAnchor to answerView.bottomAnchor
func submitAnswer() {
tableViewTopConstraint.isActive = false
tableViewTopAlternateConstraint = true
}
func newQuestion() {
tableViewTopConstraint.isActive = true
tableViewTopAlternateConstraint = false
}
}
I'm building a question/answer type of app and the two subviews are different sizes for design reasons. I have it set so that it toggles between the two subviews depending on the current state (toggling back for a new question when the user taps to advance), and it works fine...
...until I go to a different tab on the UITabView that encloses everything (e.g. to change the settings then resume testing)
The moment the tab changes it's like the NSLayoutConstraint outlets no longer exist. The orders to change them still process (I've verified this in the console), but they do nothing.
I've tried declaring the outlets as strong (there was no difference in behavior)
I've removed the outlets and managed them in code (it worked the first time, but afterward it stretched the shorter QuestionView's height to match tableView's new top position instead of moving tableView up to the bottom of QuestionView as was intended)
I've tried implementing a UITabViewController so that I could call tabBar(_:didSelect:) and replace the view controller with a brand new instance of MyViewController() whenever I switch back to that tab (It loads the first time, but when I try to switch tabs it finds nil when accessing any of the IBOutlets...even though I didn't tap on the tab for the testing view and filtered by item.tag when replacing the existing view controller)
Any suggestions on how else to attack this problem?
First, don't set #IBOutlet properties to weak. I know that's the default, but it's not correct.
If you have this:
#IBOutlet weak var tableViewTopAlternateConstraint: NSLayoutConstraint!
connected to a constraint via Storyboard, and you do this:
tableViewTopAlternateConstraint.isActive = false
you just removed that constraint from existence.
In addition, if you have two different Top constraints in Storyboard, you should be getting an Error indicator as they cannot be satisfied.
Better to either change the Priorities, or use a single constraint and change the .constant value.
So, two constraints in Storyboard:
set the "default" constraint to Priority: High (750)
set the "alternate" constraint to PriorityL Low (250)
and your code becomes:
func submitAnswer() {
tableViewTopConstraint.priority = .defaultLow
tableViewTopAlternateConstraint.priority = .defaultHigh
}
func newQuestion() {
tableViewTopAlternateConstraint.priority = .defaultLow
tableViewTopConstraint.priority = .defaultHigh
}

InputAccessoryView with custom view created in IB

I've read a lot of material on this topic but most of them create custom view programatically.
Is it possible to use InputAccessoryView with a custom view created in IB? In storyboard I've added textInputView, inside which I've added text view and send button etc as seen in the screenshot below.
I've following code so which removes Table View for some reason so I can't get it working. I've added tableview in the storyboard.
I've shown here only InputAccessoryView related code.
class InputAccViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var textView: UITextView!
#IBOutlet weak var textInputView: UIView!
// other code
override var canBecomeFirstResponder: Bool { return true }
override var inputAccessoryView:UIView {
get{
return self.textInputView
}
}
override func viewDidLoad() {
super.viewDidLoad()
textInputView.removeFromSuperview()
// other code
}
// other code tableview delegates etc...
}
Left screenshot is with the accessory view code which doesn't show table view. If I comment out accessory view related code it does show table view as in the right screenshot.
Seems you might be constraining the UITableView's bottom to the textInputView's top. When you are setting the textInputView as the inputAccessoryView of the UIViewController this no longer works as expected. When setting the textInputView as the inputAccessoryView make sure you constraint the bottom of UITableView to the bottom of UIViewController's view.

InputAccessoryView move table view up and down with keyboard show/hide interactively

I've been checking out various tuts on how to move table view up/down with keyboard interactively when using InputAccessoryView but I didn't find any solution. Most of the solutions suggest using keyboard notifications which defeats the purpose of having InputAccessoryView for me. I started using InputAccessoryView only to avoid kb notifications as drag to dismiss keyboard interactively was difficult to implement using kb notifications.
How do we move table view up and down with InputAccessoryView? Any hint will do as I already know how to move table view up and down with kb notifications.
Storyboard setup -> https://i.stack.imgur.com/0QJyn.png
Screen recording -> https://imgur.com/a/S5Oi9VS
Snippet of relevant code
class InputAccViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var textView: UITextView!
#IBOutlet weak var textInputView: UIView!
// other code
override var canBecomeFirstResponder: Bool { return true }
override var inputAccessoryView:UIView {
get{
return self.textInputView
}
}
override func viewDidLoad() {
super.viewDidLoad()
textInputView.removeFromSuperview()
// other code
}
// other code tableview delegates etc...
}
While facing the same issue a while back I found a simple solution that worked for me. I'm putting it here so that it could be helpful for others too. What I did was just replace the UIViewController with a UITableView constraint all sides to the UIView subclass view with just a UITableViewController and use the tableView that is in build into it to populate the data. All the moving content above the keyboard feature is built right into UITableViewController. Since I did my layout programmatically it was pretty easy for me to try this out and make it work. You seem to have done it via a storyboard try this out for yourself and you'll feel relieved by the result. By the end this is implemented your code should look from this:
class InputAccViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
To this:
class InputAccViewController: UITableViewController {
// `#IBOutlet weak var tableView: UITableView!` removed
}

Change UIView height dynamically

I'm trying to allow the height of the subview (the white box inside the view. The view controller swift file is a separate XIB file) depending on the amount of content in it. How do I do this?
This is what I have so far for it:
#IBOutlet weak var myScrollView: UIScrollView!
#IBOutlet weak var myContentView: UIView!
override func viewDidLayoutSubviews()
{
let scrollViewBounds = myScrollView.bounds
let containerViewBounds = //I am not sure how to do the rest
}
The best way to achieve this is to use autolayout. You have great tutorail here:
http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1
If you don't want to use it, set reference for your view inside your view controller for that view, and use various functions to calculate height. There are several ways for labels ( Adjust UILabel height to text ), text field( How to set UITextField height? ), etc.

"inflating" xib programmatically in swift using Auto-Layout

I've asked a simular question before with no working result yet, but it might have too much "stuff" which is irrelevant to the exact issue I'm experiancing:
I used to be an Android-only developer in my current position and did not do any iOS apps before this so I might be troubling myself with the wrong stuff.
I want to load an view from xib which has a parent class I'd love to be able to do something like this (e.g. in UIViewController):
override func viewDidLoad() {
let view = MyView()
view.unlimitedLabel.text = "bla bla unlimited character string"
self.view.addSubView(view)
}
The MyView would be like this (I'm omitting what I added just to keep it clean):
import UIKit
class MyView : UIView {
#IBOutlet var view: UIView!
#IBOutlet weak var deadlineLabel: UILabel!
}
So what init's are recommended, what should I apply to the view to make it respect the autoLayout? I understand it will be hard to do the AutoLayout when the view doesn't know it's parent and such.
for now I'm usually overriding all init's and call a private func like
private func setup() {
NSBundle.mainBundle().loadNibNamed("MyView", owner: self, options: nil)
view.setTranslatesAutoresizingMaskIntoConstraints(false)
addSubview(view)
}
This barely ever works as expected, I have it working for height sometimes, but then the width is not being respected it just takes the xib's width. In general the view will have the xib's in UIBuilder size.
The xib is set correctly it's working fine for tableViewCell's right now. And the "MyView" class is set to the xib's file owner, outlets linked.
Note: I'm on iOS7 using Swift

Resources