UITapGestureRecognizer Crashes App..? - swift

I am using image views to display users' friends lists. The user should be able to tap on a friend's icon and be taken to another screen. The code I've written works perfectly on the Xcode simulator. However, when running on a device, the app crashes every single time as soon as I tap an icon.
I really am unsure where to even start debugging this, even after tons of google-ing. Any advice/ help is appreciated.
I have read that my specific error potentially has something to do with memory allocation(?) but still unsure where to start/ what to do. When I check my device logs, the exception type shows this: Exception Type: EXC_BAD_ACCESS (SIGSEGV). I've followed tutorials on finding zombies and it did not help. Thank you.
I'm not really sure what code to post, but since you'll probably want to make sure I am setting up the icons correctly: (i've deleted some code to keep it simple as possible; this is running in a loop to create x amount of icons)
let iv = UIImageView()
iv.translatesAutoresizingMaskIntoConstraints = false
iv.image = image!
iv.tag = j
iv.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.iconTapped))
iv.isUserInteractionEnabled = true
iv.addGestureRecognizer(tapGestureRecognizer)
iconTapped function:
func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {
print("TAPPED NUMBER: \(gestureRecognizer.view?.tag)")
tappedIcon = CurrentSixFriendsList[(gestureRecognizer.view?.tag)!]
let nextVC = ConfirmOpponentViewController()
nextVC.chosenOpponent = tappedIcon
navigationController?.pushViewController(nextVC, animated: true)
}
UPDATE:
I've commented out all code on nextVC and all code in iconTapped except for a print statement. The app still crashes on device only when I tap any friend icon.
func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {
print("tapped")
}
SECOND UPDATE:
so i commented out all the code for rendering the image views and I hardcoded an image view. (just one image view) with a static image from my project. the image view displays and the app crashes even when i tap on this imageView. why is it acting so strange!? i'm going crazy...
I added this code in VDL just to experiment:
let iv = UIImageView()
iv.isUserInteractionEnabled = true
iv.translatesAutoresizingMaskIntoConstraints = false
iv.image = #imageLiteral(resourceName: "settings icon")
view.addSubview(iv)
iv.widthAnchor.constraint(equalToConstant: 100).isActive = true
iv.heightAnchor.constraint(equalToConstant: 100).isActive = true
iv.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
iv.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(iconTapped))
iv.addGestureRecognizer(tapGestureRecognizer)

Finally, found out why it was crashing.
Your tapped function:
func iconTapped(gestureRecognizer: UITapGestureRecognizer, _ sender: AnyObject) {
print("tapped")
}
should be like this:
func iconTapped(gesture: UITapGestureRecognizer) {
// To get the sender's tag, do this:
print(gesture.view.tag)
}
Also adjust the #selector to the right function.
When setting a selector to UITapGestureRecognizer, the recognizer object will call the selector with only the sender, and you can not add another argument to that function.
So, the root cause of the crash is because you are trying to fit a method with one argument (which is what the gesture sends out) into a method with two arguments. This crash was very interesting because it worked all right on the simulator but only crashed in an actual device. I guess it was because the simulator and the device handle functions with extra parameters differently? (simulator ignores it vs. device crashes). If you find anything deeper as to why exactly this was happening, I would love to know.

Most probly your CurrentSixFriendsList doesnot have value of gestureRecognizer.view?.tag)!.But a breakpoint before this line
tappedIcon = CurrentSixFriendsList[(gestureRecognizer.view?.tag)!]
Even then if you dont get an error then install crashlytics.This is a tool which will tell your crash issue.

Replace your tap gesture code & From swift 3.x you need to use #selector
let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(dismissKeyboard))
self.view.addGestureRecognizer(tapGesture)
#objc func dismissKeyboard(gesture: UITapGestureRecognizer) {
view.endEditing(true)
}

Related

How to make an image disappear after clicking it?

I want to make a small image.png disappears after clicking it.
I'm a newborn of swift so I'm using single view on Playground for my experiments. Anyone can help me please?
add this code while creating your_imageView
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
your_imageView.isUserInteractionEnabled = true
your_imageView.addGestureRecognizer(tapGestureRecognizer)
func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
let tappedImage = tapGestureRecognizer.view as! UIImageView
tappedImage.isHidden = true
}

Need to do double click in a button to change the image

Swift
I am new in swift and I am doing a tic tac toe, with some improvements in the gaming, so I need to put some condicionals, but my real problem is when I am playing I need to do double click to change a button with no image to a button with image and this is anoying to the player.
I put somes Outlet because I need to desable some buttons (this depend of the players) but I think this no has relation with my mistake because one day I errased all my Outlets to found my mistake and I still needed to do double click, thanks for helping and have a nice day.
You can specify the number of taps required for a UITapGestureRecognizer. Instead of the view, you could set to the button/image.
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
tap.numberOfTapsRequired = 2
view.addGestureRecognizer(tap)
}
#objc func doubleTapped() {
// do something here
}

UILongPressGestureRecognizer Not Running Action or Is Not Recognized Despite Being Added to Views GestureRecognizers and Being Configured

I am using swift for an ios app, and it (of course) uses various gesture recognizers. I have not had too many problems with them up until now: I am using a UILongPressGestureRecognizer, and I think it is configured correctly (I just looked in the documentation and set my instance of UILongPressGestureRecognizer to reasonable values). The problem is that its selector function is not running. Here is my code.
let longPress : UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(sender:)))
longPress.allowableMovement = 20
longPress.minimumPressDuration = 0.5
longPress.numberOfTapsRequired = 0
longPress.numberOfTouchesRequired = 1
self.view.isUserInteractionEnabled = true
self.view.addGestureRecognizer(longPress)
print("self.view gesture recognizers: \n")
print(self.view.gestureRecognizers as Any)
I have messed around a little with all the values for the configuration (i.e. numberOfTapsRequired). And here is my selector function/action:
#objc func longPressAction(sender : UIGestureRecognizer) {
print("Long Press Recieved")
//Other code here
}
Here is the developer page for UILongPressGestureRecognizer:
https://developer.apple.com/documentation/uikit/uilongpressgesturerecognizer
Thanks for any help, and if you need any clarification about what I am doing, please ask.

ScrollView UIRefreshControl is not calling function

I added a refreshControl to a scrollView in iOS 10 an swift 3, but the added function is not called.
Here is my code.
let rc = UIRefreshControl()
rc.addTarget(self, action: #selector(refresh), for: UIControlEvents.valueChanged)
if #available(iOS 10.0, *) {
scrollView.refreshControl = rc
}
...
#objc func refresh(_ sender: AnyObject) {
let response = serverHelper.send(word: JSONParser.getAllGamesForPlayer(player: localPlayer))
let games = JSONParser.parseToArrayDic(string: response)
print("All games \(games)")
addAllGameButtons(games: games)
sender.endRefreshing()
}
I want that the refreshContol is calling the refresh function.
But the function is never called.
What I'm doing wrong here?
EDIT
The refreshControl is working, but the problem is, that I have to scroll down to the end of the screen so that the function gets called.
My scrollView has a high of 1200 px.
Anyone who knows how to solve this?
I had this bug when my view controller had size: freeform of 1500px on the storyboard.
When I changed it to fixed size & inferred, the refresh started to work as expected.
Looks like a bug on Apple's side that the refresh control, value change distance is set when the view is loaded from Xib/Storyboard but not updated when it is laid out for the device.

Searchbar cancel button not visible only on iPad

First I want to say I didn't find any good answer about it in Swift. I created search bar. On button click it shows and on cancel it hides the searchbar. It is working properly, cancel button is visible on all iPhones but for some reason not on iPad. What should cause this?
That is how I create the searchbar:
//Create searchbar
func createSearchBar(){
searchBar.showsCancelButton = true
searchBar.tintColor = UIColor(red:0.184, green:0.996, blue:0.855, alpha:1.00)
searchBar.placeholder = "Search brands"
searchBar.delegate = self
searchBar.hidden = false
searchBar.alpha = 0
navigationItem.titleView = searchBar
navigationItem.setLeftBarButtonItem(menuButton, animated: true)
navigationItem.setRightBarButtonItem(searchButtton, animated: true)
UIView.animateWithDuration(0.5, animations: {
self.searchBar.alpha = 1
}, completion: { finished in
self.searchBar.becomeFirstResponder()
})
}
Faced the same one of my project. I've posted on apple forum and lot of developers commented as a xcode bug. So I added the cancel button manually for ipad views
func configureCancelBarButton() {
let cancelButton = UIBarButtonItem()
cancelButton.image = UIImage(named: "cancelButton")
cancelButton.action = #selector(viewController.ipadCancelButton(_:))
cancelButton.target = self
self.navigationItem.setRightBarButtonItem(cancelButton, animated: true)
}
And I previously posted an answer about this question. Check that too. :)
https://developer.apple.com/documentation/uikit/uisearchbar/1624283-showscancelbutton
The value of this property is ignored, and no cancel button is displayed, for apps running on iPad.
Apple add that in documents!
The UISearchbar's cancel button will work in iPads if you are NOT using the UISearchbar as NavigationBarItem.