how to find a string property that corresponds to a gesture.view in Swift? - ios

I have a json file containing an array of dictionaries:
"question":"Question text",
"answers":["Yes", "No"],
"answerTracker":["1a", "1b"]
I have created a Question Class & an Answer Button View Class to display the questions & answers in the view.
In the view controller I have so far displayed the questions, created the answer buttons, and finally, added a tapGestureRecogniser to each button.
func answerTapped(gesture:UITapGestureRecognizer) {
// Get access to the button that was tapped
let selectionButtonThatWasTapped:SelectionButtonView? = gesture.view as? SelectionButtonView
if let actualButton = selectionButtonThatWasTapped {
// Find out the index for the button that has been tapped
let selectionTappedIndex:Int? = find(self.selectionButtonArray, actualButton)
**// Find the answer tracker for the button that has been tapped?**
// Append the tracker for the selected button to the User Generated Code
if let actualAnswerTracker:String = self.answerTracker as String! {
self.userGeneratedCode.append(actualAnswerTracker)
}
In the tapGestureRecognizer method above I now need to find the corresponding answerTracker (String) for the answer button that is tapped (UIView) but can't find a way? The answerTracker string corresponding to the tapped answer is to be appended into a String array property called userGeneratedCode.
Any suggestions?

you do not need to add a tapGestureRecogniser to a button, you can add a target and selector to button anyway. If you want to know which button is pressed, you can use tag property on UIButton to check against.

Related

Adding a cell to another TableView. (selecting an item from a tableview, showing it in another tableview)

I'm building an app which which has built in with 2 different tabs. First tab is is "Home" which basically has a tableview with cells that configured from an api.(The api gets me country names for now)
Those cells also have a "Star" button which prints the data of the specific cell for now.
Second tab is "Saved" tab(SavedViewController), where I want to show the "starred" countries, using a tableview.
You can see the image below in order to get an idea for the app.
App simulation Image
The star button has a function in my CountriesTableViewCell. I'm using a saveButtonDelegate in order to let the SavedViewController know about an item is going to be saved. The code in CountriesTableViewCell for star button is as below.
#objc func buttonTapped() {
//If Button is selected fill the image. Else unfill it.
if !isSaveButtonSelected {
saveButton.setImage(UIImage(systemName: "star.fill"), for: .normal)
isSaveButtonSelected = true
saveButtonDelegate?.saveButtonClicked(with: countryData) //Checking if save button is clicked
}
}
countryData is the data that I get from the api, and this is the data I want to pass to SavedViewController.
struct CountryData: Codable {
let name : String
}
So on the SavedViewController, I'm handling the data using the SaveButtonProtocol conformance as below:
extension SavedViewController: SaveButtonProtocol {
func saveButtonClicked(with data: CountryData) {
countryDataArray.append(data)
print("saveButtonClicked")
print("countryData in savevc is \(countryDataArray)")
DispatchQueue.main.async {
self.countriesTableView.reloadData()
}
}
}
Whenever I click the star button on the first tab, this function is getting called on SavedViewController. So whenever I click to button, those print statements above work fine.
The problem is, whenever the star button is clicked, it should append the data of the current clicked cell to countryDataArray in SavedViewController. But the array is not populating as it should.
Let's say I pressed the first cell's star button, my print("countryData in savevc is (countryDataArray)") statement prints : ["Vatican City"], then I press the second cell's star button it only prints ["Ethiopia"] while it should print ["Vatican City", "Ethiopia"]
Why this issue is happening? My best guess is I'm delegating SavedViewController from the cell class so it behaves differently for every other cell. If that is the problem what should I do to solve it?
Many Thanks.
You should store your data in a shared (static array) object so you only have one source and add the saved indicator in your country struct so you do not rely on what is displayed in one view controller.

Printing random string from an array on textview

I can't seem to get my array printed onto my textview. I have an array and have set my textview (texthold) to the randomIndex of the array.. Anything you guys see I'm doing wrong?
This is my button that when clicked is supposed to get a random string from the devices array and print it into the textview field. I am getting no errors just nothing displays onto the textview when the button is clicked
#IBAction func Generate(_ sender: Any) {
let devices = ["Apple Watch", "iPhone", "iPad", "Mac", "Apple TV"]
// Generate a random index
let randomIndex = Int(arc4random_uniform(UInt32(devices.count)))
// Get a random item
let randomItem = devices[randomIndex]
texthold.text = devices[randomIndex]
}
This code works in my program. Check your layout using "Debug view hierarchy tool", maybe it will help.
And:
texthold.text = randomItem
Name methods with lowercase (Generate -> generate)
Check if your button touch calls this method
Check if your UI items have connected outlets.
There may be problem with changing text from background thread, but if you really have this method connected from storyboard/xib as method for outlet's action - this situation impossible.
And check that your code is being called on .touchUpInside action of your button (second screenshot in storyboard)!

Getting tag or index for a tap gesture recognizer

I have a uitapgesturerecognizer, for a uiview. I have 30 of these uiviews in a scrollview. Also in each of these views there is a label with different words in it for each view. Now when I hit a tap gesture recognizer, I want to access the text from the label for that particular view. Whats happening is I'm printing the words of the last view in the index. Can someone show me how I can access each view in each index.
open var Name: UILabel!
open func ynCategoryButtonClicked(_ sender: UITapGestureRecognizer) {
guard let text = Name.text else { return }
ynSearch.appendSearchHistories(value: text)
self.delegate?.ynCategoryButtonClicked(text: text)
}
The place where you are assigning your tapGesture to your "UIButtonView", add this line:
yourButton.accessibilityHint = "YourText"
And In your "buttonTapped()" method get the text like this:
let yourText = "\(sender.accessibilityHint)"
Hope this will help!
Honestly, it sounds like you should be using a UITableView. Either way though, you should alter your delegate method ynCategoryButtonClicked to also pass a reference to itself (so something like delegate?.ynCategoryButtonClicked(text: text, ynCategory: self)). Then if you go the TableView route you can find the index by using indexPath(for:UITableViewCell). Or, if you stick with the scrollview, you should be able to maintain an array of the views, and just search through them for the ynCategory.

How to detect which image has been tapped in swift

I have created 6 UIImageViews on a ViewController, and I am later going to add TapGestureRecognizers to all of them.
I want to make it so that depending on what image has been clicked, another ViewController will open and display certain information.
For this to happen, I need to know which image has been clicked. How would I do this in Swift?
UIGestureRecognizer has property 'view' this property is the view you add it to. For this example the imageView.
func tap(gesture: UIGestureRecognizer) {
println(gesture.view!.tag) // You can check for their tag and do different things based on tag
}
let img = UIImageView()
img.userInteraction = true
img.tag = 0
img.addGestureRecognizer(UITapGestureRecognizer(self, action: "tap:"))

Check UIButton already exists or not in Swift

I found Objective-C coding for this topic. But the problem is that most of the classes and functions in Objective-C is deprecated in swift programming language.
I am using a UIButton inside a UITableView with flagForAction[Boolean Value]. So what i want to achieve is that if the UIButton is created once , there is no need to recreate it. So for that i need to check whether the UIButton already exists or not. Somebody suggested me the concept of tag for this, applying a particular tag to this UIButton and checking that is exist on the view or not. But i don't know how to do that.
Setting a tag:
myButton.tag = 1234 // some unique value, probably better to define as an enum or constant
Retrieving a view by tag (likely in cellForRowAtIndexPath):
if let myButton = tableviewCell.viewWithTag(1234) { // change tableviewCell for whatever your tableview cell variable name is
// myButton already existed
} else {
// TableviewCell doesn't contain a myButton, so create one here and set the tag as above
}
in swift 2.0
for view in myview.subviews {
if let btn : UIButton = view as? UIButton {
// access button here, either tag or title etc..
}
}
I am using view as example. You can also identify a button with accessibilityIdentifier property of the button, if you dont want to use tag proprerty of button.
For example :
var button = UIButton(frame: CGRectMake(0, 0, 100, 44))
button.accessibilityIdentifier = "button 1"
self.view.addSubview(button)
Here, i created a button with accessibilityIdentifier "button 1"
While creating the next button, i will check in the subview if it contains the button with accessibilityIdentifier "button 1", as below
var subviews : NSArray = self.view.subviews
for button : AnyObject in subviews{
if(button .isKindOfClass(UIButton)){
if(button.accessibilityIdentifier == "button 1"){
println("Button Already Exists")
}else{
println("Create new button")
}
}
}

Resources