Showing and hiding object in tableViewCustomCell - swift

In my custom cell I have button which tagged in cellForRowAtIndexPath like this:
cell.downloadButton.tag = indexPath.row
By clicking on this button I want it to be hidden and another to be shown. How should I contact with specific cell knowing only tag of it's button?

Your question is hard to understand, the code you have appears to do what you're asking. Do you mean to ask how to get the cell that the button belongs to? If so inside downloadButtonClicked, you can get the cell it belongs to with sender.superview or sender.superview.superview and so on depending on how many superviews the button has. An example would look like this:
#IBAction func downloadButtonClicked(sender: AnyObject) {
let cell = sender.superview.superview as! CustomTableViewCell
cell.downloadButton.hidden = true
}

Related

Transitioning from uitableview to new viewcontroller

I'm working on the "settings" portion of my app. When one of the cells is clicked, I need to transition to a new View Controller depending on which cell was clicked.
I have found a ton of answers, but they all seem to not go far enough. I understand how to set up a segue to a new view controller and I understand how to use didSelectRowAt Indexpath to show which cell was clicked. I can figure out the transition, but I can't figure out many different transitions based on which cell was clicked.
Is there a way to do this with dynamic cells or should I be using static?
If you have fixed amount of cells, I'd go for static cells. However if you want to use dynamic cells, you can create something like enum with cases that store row index.
fileprivate enum Row: Int {
case volume = 0
case notification = 1
}
Then in didSelectRowAt delegate method:
let row = Row(rawValue: indexPath.row)!
switch row {
case .volume:
// Navigate somewhere
case .notification:
// Navigate somewhere
}

Add custom recognizer delay

I've disabled delaysContentTouches in my tableview subclass using:
delaysContentTouches = false
subviews.forEach { ($0 as? UIScrollView)?.delaysContentTouches = false }
But in one of my sections, I still want to keep the delay. Is there a way to cancel the delay for certain sections or perhaps I can add a custom recognizer delay to a section?
Sections are not actual objects within a tableView, so my answer to your first question is no. The .delaysContentTouches applies to the entire tableView.
For your second inquiry, I believe that one way it could be possible is through setting a delay for desired cells' scrollView subview. In your tableView(cellForRowAt: indexPath) func, you could have something like this:
if indexPath.section == 3 { //or whatever your desired section is
for view in cell.subviews {
if view is UIScrollView {
let currentView = view as! UIScrollView
currentView.delaysContentTouches = true
}
}
}
This will find the UIScrollView in your cell's subviews in your desired section. It will then set the .delaysContentTouches property accordingly.
I have not personally executed this code, just researched it, so let me know if it works.
Edit
Apparently the UIScrollView in UITableViewCell has been deprecated, so the above method will not work anymore.
My next best suggestion to you is to use a UILongPressGuestureRecognizer. This will not be quite the same thing as delaying the touch, but could have a similar effect in real execution.
You could use it in the same tableView(cellForRowAt: indexPath) func as so:
let press = UILongPressGestureRecognizer(target: self, action: #selector(handlePress))
press.minimumPressDuration = 2.0 //however long you want
cell.addGestureRecognizer(press)
Whatever you are trying to achieve by selecting certain rows of your tableView could be placed in the handlePress func above which would be trigged upon the long press.

NSUserDefaults changing every segue

Sorry for the newbie question but i am really stuck.
I have a UIViewController and 4 tableviews in an app. When i click on a button on the UIViewcontroller it segues to a UITableviewController called "Beach". When the user clicks on a cell of the table, it segues back to the UIViewController and displays the selected cells title as the buttons title. The problem that i am having is when i click on a nother button to a tableview and then clicks on the cell, the previous buttons title sets back to the previous title.
i have a prepare for segue function in the tables view controllers and this returns the selected table title (named : Titleoftable) to the main VC which, the strings.
the way i am currently doing it is to make a NSUserDefault below but the problem still remains the same - The value changes top "" every time i click on another table V---
let path = tableView.indexPathForSelectedRow
let cell = tableView.cellForRowAtIndexPath(path!)
let persistenceStoreKey = "MyStringKey"
let stringToStore = "\((cell?.textLabel?.text!)!)"
// Store data
NSUserDefaults.standardUserDefaults().setObject(stringToStore, forKey: persistenceStoreKey)
NSUserDefaults.standardUserDefaults().synchronize()
// Get data
let myStringt = NSUserDefaults.standardUserDefaults().stringForKey(persistenceStoreKey)
destination.textOfBeach = (myStringt)!
destination.isBeachSelected = true
}
I have been stuck on this problem for ages now! PLEASE HELP!!
PS- I am using swift-2 and Xcode7
Make sure that you are not pushing a new ViewController after you click on the tableview's cell. It gives me the impression that it might be the case since you are seeing only the title of the last cell you pressed.. Make sure you actually pop the tableview's controller instead of pushing a new one.
If you want to keep using NSUserDefaults, you could just call
navigationController?.popViewController(animated: true)
in your cellSelection function, and read the defaults value in the viewWillAppear of the main ViewController.
override func viewWillAppear(_ animated: Bool) {
let userDefault = NSUserDefaults.standard()
if let beachSelection = userDefault.string(forKey: "BeachControllerSelection") {
textOfBeach = beachSelection
isBeachSelected = true
}
//same for the rest of the other table view's selections
}

How to print "image x tapped" when user taps on one of many UIImages in the View Controller? (Swift 3)

I have a set of 12 UIImageViews in my storyboard, and, for argument's sake, I want to get each one to print to logs "You just tapped image x", when the user taps on it, where x is the number of image tapped, from 1-12). So i need to detect which image is tapped, and do something depending on that information. What would be the best way to do this, in Swift 3 ?
(I assume 12 IBActions -treat them as button with an image on background- is really bad code. Also they need to be placed on specific positions on top of a background image, so cannot use UICollectionView to do this.) Thanks
First of all, I think using a collectionView is a better approach to achieve what do you want. However, you'll need to:
Set userInteractionEnabled to true for all of your imageViews.
Set -sequential- tag for all of your imageViews, for example image1.tag = 1, image2.tag = 2 ... and so on.
Implement a method to be the target of all of your images tapping, it should be similar to this:
func imageViewTapped(imageView: UIImageView) {
print("You just tapped image (imageView.tag)")
}
Create -one single- tap gesture and assign the implemented method to its selector:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
Finally, add the tapGesture for all of your image, for example: image1.addGestureRecognizer(tapGesture), image2.addGestureRecognizer(tapGesture)... and so on.
Hope this helps.
It's not bad code per-se, but if you did it that way, or with tap gestures on each of the ImageViews you would likely want to separate out that part of the logic.
There are other approaches/views you could use to manage this kind of thing better, especially if this is supposed to scale, but with your constraints this is what I would suggest:
Either add TapGestureRecognizers to your imageViews or make them buttons, then connect all their actions to this:
#IBAction func phoneWasPressed(sender: AnyObject) {
guard let tappedImageView = sender as? UIImageView else {
return
}
switch tappedImageView {
case imageView1:
//do something
case imageView2:
// do something else
//etc.
default:
break
}
switch sender
}
I don't think it's a bad idea at all to have 12 buttons. Assign each of them a tag from 1-12 and connect them to the same IBAction.
#IBAction func didTapImageButton(button: UIButton) {
print("You just tapped image \(button.tag)")
}

How can i make several labels clickable in a shortcut?

in my code i have a tableView and several labels..
I want that the when the user click on cell and after that click on one of the labels, the text in the label will be same as the text in the row that be clicked.
Q1. How can i enable all labels to be clickable and connect to one function that will point on the specific label each time the user click on it?
Q2. I tried to make the same gesture to all labels with UITapGestureRecognizer.. apparently this gesture refers only to the last label (Lbl4 down here in code example).. it means that the text in Lbl1 in my func change only by clicking on Lbl4.. why is that? and how can i change it that it will refers to all labels?
override func viewDidLoad() {
super.viewDidLoad()
let aSelector : Selector = #selector(ViewController.lblTapped)
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector)
tapGesture.numberOfTapsRequired = 1
Lbl1.addGestureRecognizer(tapGesture)
Lbl2.addGestureRecognizer(tapGesture)
Lbl3.addGestureRecognizer(tapGesture)
Lbl4.addGestureRecognizer(tapGesture)
}
func lblTapped(){
Lbl1.text = self.currentPlayerChooseInRow
}
Thanks for advance...
Firstly, you need to understand UITableView object. UITableView is an array of cells, ok? Then, you need use some methods associated to UITableView like numberOfRowsInSection (where app knows the number of cells) and cellForRowAtIndexPath (where app knows cell will be)
About your questions, i recomend you to use outlets to connect labels, buttons, objects to the controller (try to not use gestures if it is not necessary)
Finally, object cells are programmed into cell. If you have a complex cell, you will need a custom cell controller.