iOS DropDown CocoaPod - drop-down-menu

I am trying to get to grips with iOS DropDown cocoapod
import UIKit
import iOSDropDown
class CountryConfirmViewController: UIViewController {
//var buttonTapped = 0
#IBOutlet weak var countryLabel: DropDown!
override func viewDidLoad() {
super.viewDidLoad()
dropDown()
}
#IBAction func confirmCountry(_ sender: UIButton) {
performSegue(withIdentifier: "goToUser", sender: self)
}
func dropDown() {
countryLabel.optionArray = ["First", "Second", "Third"]
countryLabel.showList()
}
}
The code above produces a dropdown menu but I can't get the data chosen by the user and move it to another controller. I can't find anything on the CocoaPod website about it or anywhere else.

You need to follow related library's documentation properly, I've found this code block;
dropDown.didSelect{(selectedText , index ,id) in
self.valueLabel.text = "Selected String: \(selectedText) \n index: \(index)"
}
You can grab selection, from the method didSelect

Related

UserDefault in Xcode is not saving the text

This code won't save the text for same reason. How to fix it?
import UIKit
class ViewControllertextview: UIViewController {
#IBOutlet weak var text: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
_ = UserDefaults.standard
let value = UserDefaults.standard.string(forKey: "onekey")
if value != nil{
text.text = value
}
else {
text.text = "Here you can make Notes"
}
}
let defaults = Foundation.UserDefaults.standard
#IBAction func Sbutton(_ sender: Any) {
UserDefaults.standard.set(text.text, forKey: "onekey")
}
#IBAction func ggbutton(_ sender: Any) {
}
}
UserDefaults don't immediately write data to storage. You can try calling UserDefaults.standard.synchronize() to save immediately, right after UserDefaults.standard.set(..

Obtaining a View Controller Reference

I read quite a few questions and answers no this problem. Some are for Ojective C. Some are for iOS. The ones that were close to what I need didn't work.
I've set up a protocol for delegation. It doesn't work. The problem is that delegate variable isn't set. I need the reference to an active controller.
Delegator
protocol SwitchTabDelegate: class {
func selectTab(tab: Int)
}
class ViewController: NSViewController {
weak var delegate: SwitchTabDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func selectCompositions(_ sender: NSButton) {
if let delegate = self.delegate {
delegate.selectTab(tab: 2)
}
else {
print("self.delegate is nil")
}
print("delegate called")
}
}
Delegatee
class TabViewController: NSTabViewController, SwitchTabDelegate {
var viewController : ViewController?;
override func viewDidLoad() {
super.viewDidLoad()
//viewController = storyboard?.instantiateController(withIdentifier: "viewController") as? ViewController
// viewController?.delegate = self
// print(viewController)
}
func selectTab(tab: Int) {
print("In the delegate")
switchToDataTab()
}
func switchToDataTab() {
Timer.scheduledTimer(timeInterval: 0.2, target: self,
selector: #selector(switchToDataTabCont),
userInfo: nil, repeats: false)
}
func switchToDataTabCont(){
self.selectedTabViewItemIndex = 2
}
}
The delegatee is the main NSViewContoller. On the storyboard, it contains two buttons and a Container view controller. Embedded in the container view controller is the TabViewController, the delegatee. You can see in the delegatee where I tried to get a reference. It does get a reference, presumably to the newly instantiated instance. I need a reference to the original view controller that was spun up when the application started.
Answer
I added the following code to the delegator:
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
let controller = segue.destinationController as! TabViewController
self.delegate = controller as SwitchTabDelegate
}
That's not how it should work following the design pattern. The delegator should have no knowledge of the delegatee. I've spent way too much time on this issue so a hack is going to do.
When using storyboards, you want to "push" references to children when they are created vs. pulling them from an upstream controller. This is what -prepareForSegue:sender: is used for.

Why am I receiving these errors when trying to pass a variable on a segue in swift?

I am trying to build upon answer which I was given here. What I am trying to is very simple - I want a text field which you can enter text into. You press the go button and it takes you to a new view and replaces the text on a label on that page with whatever the user entered in the box. The is the code I am using on the first page.
import UIKit
class ViewController: UIViewController {
#IBOutlet var entry: UITextField!
let dictionary = entry.text // Line 7 ERROR
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTwo"
{
if let destinationVC = segue.destinationViewController as? viewTwo{
destinationVC.dictionary = self.dictionary // Line 24 ERROR
}
}
}
#IBAction func goToViewTwo(sender: AnyObject) {
performSegueWithIdentifier("viewTwo", sender: self)
}
}
I am only including the code from the first view because i know the code from the second view is working.
I didn't encounter an error until I tried to use the text field - before when I just had a pre-choses text to transfer over it worked. Before, instead of having let dictionary = entry.text I had let dictionary = "foo" and it worked.
So my question is exactly the same thing but have a text field instead of pre-chosen text - what I really want to know is why my code didn't work before.
The errors I got were on line 7 (I have labeled the lines above which had the errors) - 'ViewController.Type' does not have member names 'entry' and there was also an error on line 24 but I suspect this is related to this error and will be fixed if this error is also fixed. Just incase though, the error on line 24 was: 'ViewController.Type' does not have member names 'dictionary'
Thank you.
You should set the dictionary to var dictionary = "" in the declaration. You use var instead of let here, so that you can change the value of the dictionary later.
Then inside your #IBAction func goToViewTwo(sender: AnyObject){} method, you set the self.dictionary = entry.text
#IBAction func goToViewTwo(sender: AnyObject) {
dictionary = entry.text
performSegueWithIdentifier("viewTwo", sender: self)
}
Alternatively, you can just do the following inside prepareForSegue() method.
This way, you dont need to declare a dictionary to hold the text value of your UITextField, you can just pass the text value from your entry to the second view controller's dictionary variable.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTwo"
{
if let destinationVC = segue.destinationViewController as? viewTwo{
destinationVC.dictionary = self.entry.text
}
}
}
A dictionary is not constant, so declare it as lazy var, not let:
lazy var dictionary: String {
return entry.text
}()

How do I get the return key to perform the same action as a button press in Swift?

I want to know how you allow an action to be made by either pressing the return key on the software keyboard or by tapping a UIButton.
The UI button is already set up to perform an IBAction.
How do I also allow users to press the return key on the keyboard to perform the same action?
Make sure your class extends the UITextFieldDelegate protocol
SomeViewControllerClass : UIViewController, UITextFieldDelegate
You can perform action as follows:
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
//textField code
textField.resignFirstResponder() //if desired
performAction()
return true
}
func performAction() {
//action events
}
UPDATE
If your deployment target is iOS 9.0 or later, you can connect the “Primary Action Triggered” event of your text field to an action, like this:
ORIGINAL
Make your view controller adopt the UITextFieldDelegate protocol.
Set your text field's delegate to your view controller.
Implement textFieldShouldReturn: to call your action.
Swift 4.2 :
Other approach for the textfield created programmatically and doesn't need delegate :
MyTextField.addTarget(self, action: #selector(MyTextFielAction)
, for: UIControl.Event.primaryActionTriggered)
And then perform your action like below :
func MyTextFielAction(textField: UITextField) {
//YOUR CODE can perform same action as your UIButton
}
If your deployment target is iOS 9.0 or later, you can connect the “Primary Action Triggered” event of your text field to an action, like this:
I was not able to get the "Primary Action Triggered" to work as suggested. I used "Editing Did End" and that works for now Screenshot of Editing Did End
Here is a complete example, with both:
button-action to write and also to clear label and text when pressing button repeatedly it alternates both actions
return-in-keyboard when pressing key it triggers action and also resigns first responder
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var label1: UILabel!
var buttonHasBeenPressed = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
textField1.delegate = self
}
#IBAction func buttonGo(_ sender: Any) {
performAction()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
performAction()
return true
}
func performAction() {
buttonHasBeenPressed = !buttonHasBeenPressed
if buttonHasBeenPressed == true {
label1.text = textField1.text
} else {
textField1.text = ""
label1.text = ""
}
}
}

Computed property causes application crash

I'm porting the Apple class ImageAndTextCell to swift and use it inside a NSTableView, it was a trivial task but when I click on table row the application crashes.
I suppose the crash is due to a deallocation problem but I don't understand how to fix it.
The app crashes with the error: Thread 1: EXC_BAD_ADDRESS (code=EXC_i386_GPFLT), no other message is present so debugging the error is hard
I've isolated the code to easily reproduce the crash.
My ImageAndTextCell is shown below, it declares an icon property and access to it using the computed property image
import Foundation
import Cocoa
class ImageAndTextCell : NSTextFieldCell {
private var icon : NSImage?
override var image : NSImage! {
get {
return icon
}
set {
if newValue !== icon {
icon = newValue
if let im = newValue {
im.size = NSMakeSize(CGFloat(16.0), CGFloat(16.0))
}
}
}
}
deinit { println(" is being deinitialized") }
override func copyWithZone(zone: NSZone) -> AnyObject! {
var cell = super.copyWithZone(zone) as ImageAndTextCell
cell.icon = icon
return cell
}
}
The Application delegate is
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate {
#IBOutlet weak var window: NSWindow!
var items = [String]()
override func awakeFromNib() {
items.append("/Users/dave/trash/test.txt")
}
func numberOfRowsInTableView(tableView: NSTableView!) -> Int {
return self.items.count
}
func tableView(tableView: NSTableView!, objectValueForTableColumn tableColumn: NSTableColumn!, row: Int) -> AnyObject! {
return self.items[row]
}
func tableView(tableView: NSTableView, willDisplayCell cell:AnyObject!, forTableColumn tableColumn:NSTableColumn!, row:NSInteger) {
let item = self.items[row]
var fieldCell = cell as NSTextFieldCell
fieldCell.drawsBackground = false
// commenting the line below the app works fine but obviously the cell doesn't show the image
fieldCell.image = NSWorkspace.sharedWorkspace().iconForFile(item)
}
}
copyWithZone and deinit are called every time I click on the row so I suppose some pointer is released before the time
The table cell 'custom class' is set inside Interface Builder to ImageAndTextCell
Any idea?

Resources