How would I go about adding a uiview vertically above a uiview within an inputAccessoryView? - swift

I'm trying to add a uiview containing multiple buttons, above my current input accessory view. My current input accessory view is a growing textField (like iOS standard Text Message app).
class ViewController: UIViewController {
let textInputBar = ALTextInputBar()
// The magic sauce
// This is how we attach the input bar to the keyboard
override var inputAccessoryView: UIView? {
get {
return textInputBar
}
}
// Another ingredient in the magic sauce
override func canBecomeFirstResponder() -> Bool {
return true
}
}
Example of what I'm trying to do, the app (Facebook Messenger) has a growing textfield or textinput, and in this case, an bar of buttons bellow.
My current view, as mentioned earlier.

try this code
class ViewController: UIViewController {
#IBOutlet weak var myTextField: UITextField!
var textInputBar:UIView = ALTextInputBar()// if it is a uiview type
override func viewDidLoad() {
super.viewDidLoad()
myTextField.inputAccessoryView = textInputBar
}
}

Related

Add custom button UISearchController in swift

i want to add a custom button on UISearchController in swift.
Like this image i want to add the custom button. In this image it is a search bar. The plus button will show if there is text in the search bar and it will disappear if search bar is empty. can any one help me to implement it.
When the TextField changes, check for whitespace.
Hide or position the button depending on whether it is blank or not.
After the view is loaded, the text field is blank, so it is initialized with ishidden().
I hope my answer is helpful to you.
SearchViewController.swift
import UIKit
class SearchViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var searchTextField: UITextField!
#IBOutlet weak var plusButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
searchTextField.delegate = self
plusButton.isHidden = true
}
func textFieldDidChangeSelection(_ textField: UITextField) {
if searchTextField.text == "" {
plusButton.isHidden = true
} else {
plusButton.isHidden = false
}
}
}
Preview

Is it possible to modify the properties of a subclass from a parent class in Swift 4?

Via a method or closure, perhaps?
I created a subclass view controller of my superclass/parent view controller and placed labels with placeholder text in that subclass view controller.
I want to set the labels' values to blank strings from the superclass/parent view controller, or, specifically, from an IBAction function that causes the subclass view controller to appear.
Here is the code, first from the parent class, then from the subclass...
'''
class ViewController: UIViewController {
#IBAction func leavingView(){
self.EntryViewController.entryDateLabel.text = ""
self.EntryViewController.entryLabel.text = ""
self.dismiss(animated: true, completion: nil)
}
'''
then from the subclass...
'''
class EntryViewController: ViewController {
#IBOutlet var entryDateLabel: UILabel!
#IBOutlet var entryLabel: UILabel!
}
'''
I have come up with 2 solutions to this problem, without having the parent view controller know about its subclass.
In the first example the parent sets properties on itself that the child listens to (via the didSet method, it then updates its view accordingly. However, this isn't ideal because the entryDate and entry string fields are useless on their own, almost redundant in the parent.
class ParentViewController: UIViewController {
var entryDate: String?
var entry: String?
#IBAction func leavingView(){
self.entryDate = ""
self.entry = ""
self.dismiss(animated: true, completion: nil)
}
}
class ChildViewController: ParentViewController {
#IBOutlet var entryDateLabel: UILabel!
#IBOutlet var entryLabel: UILabel!
override var entryDate: String? {
didSet {
guard isViewLoaded else {
return
}
entryDateLabel.text = entryDate
}
}
override var entry: String? {
didSet {
guard isViewLoaded else {
return
}
entryLabel.text = entry
}
}
}
In my opinion, the second solution is clearer and keeps implementation details more separate because you're using instructions or events to notify the child view controllers.
class ParentViewController: UIViewController {
#IBAction func leavingView(){
self.dismiss(animated: true, completion: didLeaveView)
}
func didLeaveView() { }
}
class ChildViewController: ParentViewController {
#IBOutlet var entryDateLabel: UILabel!
#IBOutlet var entryLabel: UILabel!
override func didLeaveView() {
entryDateLabel.text = ""
entryLabel.text = ""
}
}
Since your requirement is not that much clear I have created a demo for you and into that demo I have added child ContainerViewController into parent ViewController and from that parent view controller you can change UILabel text when you click on UIButton of parent ViewController and code will be for ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func btnFromParentViewTapped(_ sender: Any) {
//Here get the child of your parent view controller
if let containerView = self.children[0] as? ContainerViewController {
containerView.lblContainer.text = ""
}
}
}
and ContainerViewController code will be:
class ContainerViewController: UIViewController {
#IBOutlet weak var lblContainer: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Don't need to add much here because you are accessing it from parent view.
And your result will be:
As you can see when I click on button which title says Change Container label text the label text from ContainerViewController set to empty string.
For more info check THIS demo project.

Change cell title in TableViewController in another ViewController

I'm trying to change the title in a TableViewController from another ViewController. (see image)
The second ViewController is the one with the 3 cells and the third one is the one with a textfield (inputText in code), a button (changeText) and a label (outputLabel). I would like this app to remember what I put in the text field when I go back to the table view and then back into the ViewController. What happens now is:
- I change the text, hit the button and the label changes.
- I go back to the TableViewController and then I go into the ViewController that I was just in with a changed label
- The label is what it was before...
How can I make the app 'remember' what I put in in the text field and what the label was like? My code (ViewController.swift, I linked the 3rd controller to this file, haven't linked the 2nd controller to anything (yet?)):
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var outputLabel: UILabel!
#IBOutlet weak var inputText: UITextField!
#IBAction func changeText(_ sender: UIButton) {
outputLabel.text = inputText.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.
}
Thanks in advance!
You can reference your ViewController in first controller (TableViewController),
make public inputText
#IBOutlet public weak var inputText: UITextField!
and in viewDidAppear get your text
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let text = ViewControllerVar.inputText.text //your text
}

UIview kept going at the bottom of the UIViewcontroller

My LoginViewController has a UIView that has 2 UItextfield and 1 UIbutton. The moment the user start writting the UIView should go up and leave space for the keyboard. However my problem is when the keyboard disappear the UIView did not go at its initial position. Can anyone help me please Thank you ... (my code is below)
func keyboardON(sender: NSNotification) {
let info = sender.userInfo!
var keyboardSize = info[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue().size
println("keyboard height \(keyboardSize.height)")
var frame = otherContainerView.frame
println("MainScreen :\(UIScreen.mainScreen().bounds.height)")
frame.origin.y = UIScreen.mainScreen().bounds.height - keyboardSize.height - frame.size.height
otherContainerView.frame = frame
}
func keyboardNotOn(sender: NSNotification) {
let info = sender.userInfo!
var keyboardSize = info[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue().size
println("keyboard height \(keyboardSize.height)")
var frame = otherContainerView.frame
frame.origin.y = UIScreen.mainScreen().bounds.height - frame.size.height
otherContainerView.frame = frame
}
I would suggest that you change this view controller to a UITableViewController with static cells. When using a UITableViewController, the scrolling is automatically handled, thus making your problem not problem at all.
If I understand your initial question correctly, you are trying to create a login screen in a UIViewController, which is fine, but much harder than it would be to simply create a UITableViewController. The image above was made with a UITableViewController. When the text fields are selected, it slides up, and when they are deselected, it moves back to it's initial view. If you switch to a UITableViewController, (even if you place both UITextFields and the button in one cell), you won't need to do any of this programmatically. The storyboard will handle the desired changes.
import UIKit
class LoginTableViewController: UITableViewController {
#IBOutlet weak var usernameTextField : UITextField!
#IBOutlet weak var passwordTextField : UITextField!
#IBAction func login (sender: UIButton) {
//login button
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//If you choose to use 3 cells in your storyboard (like I've done with my login screen) you will return 3 here. If you choose to put all of the items in one cell, return 1 below.
return 3
}
}

Getting nil value on textview and button

Hello im am making an app where the user can press a button and a random link shows upp. I have in the textfile tried to name blblbl.delegate = self but when running the code it suddenly says that all of my textview and buttons has the value of nil.
class ViewController: UIViewController, UITextViewDelegate,
NSObjectProtocol {
#IBOutlet weak var firstbutton: UIButton!
#IBOutlet weak var firsttextview: UITextView!
let links = ["http://www.google.com","http://www.yahoo.com",
"http://www.discovery.com"]
var currentLinkIndex : Int = 0
override func viewDidLoad() {
Firsttextview.delegate = self
configureTextView()
super.viewDidLoad()
}
func configureTextView() {
func textView(firsttextview: UITextView!, shouldInteractWithURL
URL:
NSURL, inRange characterRange: NSRange) -> Bool {
let url = NSURL(string:links[currentLinkIndex])
UIApplication.sharedApplication().openURL(url!)
return false
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func firstaction(sender: UIButton) {
let random : Int = Int(arc4random()) % 3
Firsttextview.text = links[random]
currentLinkIndex = random
}
}
How do a solve this problem? Does i some how have to give the textview and button a value! Thanks in advance!
I guess you need to change :
Firsttextview.delegate to firsttextview.delegate and
Firsttextview.text = links[random] to firsttextview.text = links[random]
I tried to recreate your example by :
Creating a button in the storyboard
Creating the textview in the storyboard
Create + drag and drop to my ViewController Class the IBOutlet firstbutton from the button in the storyboard
Create + drag and drop to my ViewController Class the IBOutlet firsttextview from the textview in the storyboard
Create + drag and drop to my ViewController Class the IBAction firstaction from the button in the storyboard
If the button and the label are created in the storyboard, they don't need to be initialized in your code.
By doing this, your code worked for me.