I'm currently having problems for my label to read the addition of 3 textfield values automatically, without a button function action. As such i only want my textfield to be an Int input only. There's a screenshot attached below for better reference. Appreciate those who can help me with this. Thanks!
ViewController
import UIKit
class TryingoutController: UIViewController {
#IBOutlet var impact: UITextField!
#IBOutlet var rigour: UITextField!
#IBOutlet var response: UITextField!
#IBOutlet var total: UILabel!
One way is to add self as the target to the text fields, for the control event .editingChanged
impact.addTarget(self, action: #selector(textChanged), for: .editingChanged)
// do the same for other textfields
Then declare a textChanged method. This should handle what happens when the texts in the text fields change. One implementation would be to add up all the values in the text fields (if any, and is valid) and display it in the label.
func textChanged() {
let impactValue = Int(impact.text!)
let rigourValue = Int(rigour.text!)
let responseValue = Int(response.text!)
total.text = String(describing:
(impactValue ?? 0) + (rigourValue ?? 0) + (responseValue ?? 0)
)
}
Optionally, you can conform to UITextFieldDelegate:
class TryingoutController: UIViewController, UITextFieldDelegate {
}
and implement shouldChange according to this answer by Thuggish Nuggets. Then, set the delegates of the text fields to self:
impact.delegate = self
// do the same for other text fields.
Related
When you add a UISegmentedControl to a view, UIAccessibility will focus on it and say:
"(Selected) ItemName Button 1 of 2"
"ItemName Button 2 of 2"
I have a custom control that has UIButtons that toggle similar to a UISegmentedControl. But what I'm trying to figure out is how to get the Voice Over to announce the n of n at the end.
The closest thing that I've found is assigning the .accessibilityTraits = .tabBar on the container. The issue is that it announces:
"ItemName Button Tab 2 of 2"
But to conform to our accessibility guidelines we can't have it announce "tab".
https://developer.apple.com/documentation/uikit/uiaccessibility/uiaccessibilitytraits/1648592-tabbar
Short of just writing a custom accessibilityLabel is there anything within UIAccessibility that can handle this logic?
Set the container view's accessibilityTraits = .tabBar
Set the container view's accessibilityElements = [button1, button2]
Set each button's accessibilityTraits = .selected or .none when necessary
I have a custom control that has UIButtons that toggle similar to a UISegmentedControl. But what I'm trying to figure out is how to get the Voice Over to announce the n of n at the end.
Put each one of your UIButton elements in the accessibilityElements array of the custom control that acts like a container.
By searching a specific element in this array, you will have an index 'x' inside a total amount 'N' of buttons: "item name button x of N".
In your UIButton, set accessibilityLabel by inserting the result of the previous research.
Here's a kind of logic that should help you reach your purpose with a little bit of code as follows for instance (Xcode 10.2.1, Swift 5.0, iOS 12):
class ButtonsViewController: UIViewController {
#IBOutlet weak var myCustomContainer: UIView!
#IBOutlet weak var btn1: UIButton!
#IBOutlet weak var btn2: UIButton!
#IBOutlet weak var btn3: UIButton!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myCustomContainer.accessibilityElements = [btn1!, btn2!, btn3!]
let nbButtons = myCustomContainer.accessibilityElements?.count
for (index, elt) in (myCustomContainer.accessibilityElements?.enumerated())! {
let btn = elt as! UIButton
let btnName = btn.titleLabel?.text
btn.accessibilityLabel = btnName! + String(index + 1) + " of " + String(describing: nbButtons!)
}
}
}
I am trying to add users names that they have put in a textfield to a basic array. I don’t even know where to start!
The functionality basically is this:
User adds a name in text field
Name is stored in an array so it can be referenced again somewhere else.
As you can tell I’m new to Xcode. I have been taking classes all of which have failed to explain this process. Any help is good Help ! Please :):)
// my view controller so far
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var name1: UITextField!
#IBOutlet weak var name2: UITextField!
#IBOutlet weak var name3: UITextField!
var namesArray : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
name1.delegate = self
name2.delegate = self
name3.delegate = self
self.namesArray.append(self.name1.text!)
self.namesArray.append(self.name2.text!)
self.namesArray.append(self.name3.text!)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
if textField.returnKeyType == UIReturnKeyType.done {
self.namesArray.append(self.name1.text!)
print(namesArray)
}
return true
}
I am going to assume you have all your logic mashed into one view controller since you are still learning and not worried about larger architecture decisions yet.
At the top of your class, you need an array variable:
// Creates an array and initializes it to be empty.
var userNames: [String] = []
I suspect you also have a button, so that when you press on the button, it grabs the text from the textfield and stores it in the array. You need to set up an IBAction method for that button, and in that method...
// Grab the text, save it in the array, and clear the text.
self.userNames.append(self.myTextField.text)
self.myTextField.text = ""
Later on, you can easily see the list of userNames by accessing self.userNames. e.g.:
let firstUser = self.userNames.first
let lastUser = self.userNames.last
let user47 = self.userNames[46] // assuming you have that many users
I am completely new to coding.
I started using this app called MIMO and learned a few bits and pieces. In one chapter they let us code a simple "dice app" where by pressing a button a number from 1 - 6 appears. Now I wanted to rewrite that so that at the button press the app displays a quote from a predetermined array.
I am completely stuck, however.
Here's what I got:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var quotesLabel: UILabel!
let quotes = ["Quote1!", "Quote2!"]
let randomIndex = Int(arc4random_uniform(UInt32(quotes.count)))
let randomQuote = quotes[randomIndex]
print(array[randomIndex])
override func viewDidLoad() {
super.viewDidLoad()
}
}
Basically any arbitrary code must be run in a method, in this case in an IBAction which is triggered when the button is pressed. The method viewDidLoad is not needed.
Change the code to
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var quotesLabel: UILabel!
let quotes = ["Quote1!", "Quote2!", "Quote3!", "Quote4!"]
#IBAction func showRandomQuote(_ sender : UIButton) {
let randomIndex = Int(arc4random_uniform(UInt32(quotes.count)))
let randomQuote = quotes[randomIndex]
quotesLabel.text = randomQuote
}
}
In Interface Builder drag a button into the canvas of the view controller
Connect (⌃-drag) the button to the IBAction and the label to the IBOutlet
Run the app and press the button
I'm a new one to learn RxSwift.
I modified the Simple Numbers example in the RxSwift Example App, which will add three numbers into a result number.
I add a testStr UITextField, and an upperCase UILabel. I map testStr to uppercase and bindTo the upperCase label, that's good. And I also map testStr to its length, and bindTo the num1 field. Strange things happen, although the contents of the num1 field changes, it does not emit any event, so it has no effect on the result label. Even if I input some number into another number field, the result number does not count the num1.
Have I made any wrong use of bindTo? In what way can I make the num1 emit an event?
Thanks!!!
#IBOutlet weak var num1: UITextField!
#IBOutlet weak var num2: UITextField!
#IBOutlet weak var num3: UITextField!
#IBOutlet weak var result: UILabel!
#IBOutlet weak var testStr: UITextField!
#IBOutlet weak var upperCase: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Observable.combineLatest(num1.rx_text, num2.rx_text, num3.rx_text) {
(textval1, textval2, textval3) -> Int in
return (Int(textval1) ?? 0) + (Int(textval2) ?? 0) + (Int(textval3) ?? 0)
}
.map{$0.description}
.bindTo(result.rx_text)
.addDisposableTo(disposeBag)
let obStr = testStr.rx_text
obStr
.map {$0.uppercaseString}
.bindTo(upperCase.rx_text)
.addDisposableTo(disposeBag)
obStr
.map{ $0.characters.count }
.map{ $0.description }
.bindTo(num1.rx_text)
.addDisposableTo(disposeBag)
}
You need to use a Subject such as Variable to store the value. You can see an example of this in this answer in the section called Using Variables.
The reason it doesn't work is because rx_text will only omit a next element when it's changed by the user, not programmatically (as you're doing). This is because rx_text is really using this method from UIControl to get notified of changes to the field:
public class UIControl : UIView {
public func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents)
}
However, that method does not call the action method on target when the change happens programmatically. Only when it happens due to a user changing something.
So, you should see a next event if you were to change the field programmatically and then the user were to tap into (or out of) the field. However, that's not what you want.
Instead, refer to that answer I linked you to and it will work.
I have created a tableviewcontroller, with a dynamic prototype cell. Within this view the user has an option to type in a review of a location from a button press as well as can rate the location on a scale of 1 to 10 with a UI Slider. The review is done with a UIAlertController within the tableviewcontroller - but the UISlider is within the cell itself. I am trying to save both pieces of data to core data within the tableviewcontroller. But the UISlider rating value is not available within the tableviewcontroller - is there a way to reference it in tableview from the cell or do I need to have two separate save functions? Here is some of my code thus far - within the tableview controller it doesn't recognize the variable assigned to the UISLider value in the prototype cell. Thanks in advance for any help!
In my tableviewcell:
class WineryInfoTableViewCell: UITableViewCell {
#IBOutlet weak var ratingLabel: UILabel!
#IBOutlet weak var sliderbutton: UISlider!
#IBAction func sliderValueChanged(sender: UISlider) {
var ratingValue = Float(sender.value)
var roundedRatingValue = roundf(ratingValue/0.5)*0.5
ratingLabel.text = "\(roundedRatingValue)"
}
in my tableviewcontroller
#IBAction func save() {
if let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext {
myRatingData = NSEntityDescription.insertNewObjectForEntityForName("WineryReview", inManagedObjectContext: managedObjectContext) as wineryReview
myRatingData.wineryName = wineryNames
//myRatingData.rating = ratingLabel.text how do I call this for saving?
myRatingData.review = myRatingEntry
var e:NSError?
if managedObjectContext.save(&e) != true {
println("insert error: \(e!.localizedDescription)")
return
}
}
// If all fields are correctly filled in, extract the field value
println("Winery: " + myRatingData.wineryName)
println("Review: " + myRatingData.review)
//println("Rating: " + ratingLabel.text!) how do I call this for saving?
}
I'm still new at Swift, but I think I may have an answer to a part of your dilemma. To reference the UISlider in your table cell, you can use 'tags' to get a reference to it.
For example:
let cell = tableView.dequeueReusableCellWithIdentifier(TableViewCellIdentifiers.someCell, forIndexPath: indexPath) as UITableViewCell
let slider = cell.viewWithTag(100) as UISlider
In the above example, I would have used assigned the UISlider with a tag of 100, so I am able to get a reference to it using the cell.viewWithTag(100).
Forgive me if this doesn't work!
You could pass a WineryReview object into the cell and set its rating directly from sliderValueChanged.
In cellForRowAtIndex:
cell.wineryReview = myReviewData
In TableViewCell:
#IBOutlet weak var ratingLabel: UILabel!
#IBOutlet weak var sliderbutton: UISlider!
var wineryReview: WineryReview?
#IBAction func sliderValueChanged(sender: UISlider) {
var ratingValue = Float(sender.value)
var roundedRatingValue = roundf(ratingValue/0.5)*0.5
wineryReview.rating = roundedRatingValue
ratingLabel.text = "\(roundedRatingValue)"
}
You could call save on the context from the TableViewController if you like. I did something very similar to this in a project.