Remember state of cell after animation - swift

Would much appreciate any advice on below.
I'm trying to make my table remember state after animation is completed. Below is my table, when I press button "Invite", animation removes buttons from cell. But during scroll down and back reusableCell draws buttons again.
I decided to use Array in order to remember, which cells were animated, but do not know how not to draw some elements of cell (buttons) during cell creation.

Try this:
Create a boolean variable called animationIsCalled and set it to false.
var animationIsCalled = [Bool](repeating: false, count: numberOfTableViewCells)
#IBAction func buttonPressed(sender: UIButton){
if animationIsCalled{
//Your code is here
}
animationIsCalled[indexPath.row] = false
}
I don't know if your method is an IBAction type or not, but if it is, you can't use indexPath.row. But try to use this boolean variable idea because I've used it before and it's a pretty useful strategy.
Hope this helps.

Alex, thank you a lot for answer! After some experiments the following code worked:
//Create array to remember already animated cells
var sectionTwoSent = [String]()
//Once button tapped append user_id to array above
self.sectionTwoSent.append(self.sectionTwo[indexPath.row].user_id)
//During cell creation, make check and alpha = 0 to hide buttons
for item in sectionTwoSent {
if contact.user_id == item {
cell.inviteButton?.alpha = 0
cell.removeButton?.alpha = 0
cell.invitationDoneLabel?.alpha = 1
break
} else {
cell.inviteButton?.alpha = 1
cell.removeButton?.alpha = 1
cell.invitationDoneLabel?.alpha = 0
}
}

Related

Changing collection view's isHidden property doesn't work with Search Bar cancel button

I have a collection view that is hidden on ViewDidLoad. When a user taps on the search bar, the collection view is shown. But when I click on the cancel button in the search bar, the collection view is not hidden. I read on other posts to use .alpha = 0 to hide a view and that works. My questions are:
Why isHidden not working and .alpha is?
Is collection view still the active layer if I use .alpha = 0?
Here is the code:
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
collectionView.isHidden = true // This doesn't work
//collectionView.alpha = 0 // This works
}
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
collectionView.isHidden = false // This doesn't work
//collectionView.alpha = 1 // This works
return true
}
Animated GIF showing app working by changing alpha channel to 1 and 0
Thanks for reading my question.
This hidden property works best on UIViews (while used for many other things). It's best to embed your collectionView inside a view if you want to use the hidden property.
The default value of this property is false. As an optimization, the
collection view might not create the corresponding view when the value
of this property is true. Because there might not be a view, hidden
elements do not participate in hit testing for the collection view.
Source: https://developer.apple.com/documentation/appkit/nscollectionviewlayoutattributes/1535336-ishidden

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.

How to Disable Multi Touch on UIBarButtonItems & UI Buttons?

My app has quite a few buttons on each screen as well as a UIBarButtonItem back button and I have problems with people being able to multi click buttons. I need only 1 button to be clickable at a time.
Does anyone know how to make a UIBarButtonItem back button exclusive to touch?
I've managed to disable multi clicking the UIButtons by setting each one's view to isExclusiveTouch = true but this doesn't seem to count for the back button in the navigation bar.
The back button doesn't seem to adhere to isExclusiveTouch.
Does anyone have a simple work around that doesn't involve coding each and every buttons send events?
Many Thanks,
Krivvenz.
you can enable exclusive touch simply this will stop multiple touch until first touch is not done
buttton.exclusiveTouch = true
You could write an extension for UIBarButtonItem to add isExclusiveTouch?
you can simply disable the multi-touch property of the super view. You can also find this property in the storyboard.
you could try this for the scene where you want to disable multiple touch.
let skView = self.view as! SKView
skView.isMultipleTouchEnabled = false
I have found a solution to this. isExclusiveTouch is the solution in the end, but the reason why this property didn't do anything is because you need to set it also on all of the subviews of each button that you want to set as isExclusiveTouch = true. Then it works as expected :)
It's working fine in Swift
self.view.isMultipleTouchEnabled = false
buttonHistory.isExclusiveTouch = true
In addition of #Luky LĂ­zal answer, you need pay attention that all subviews of a view you want disable multi-touching (exactly all in hierarchy, actually subviews of subviews) must be set as isExclusiveTouch = true.
You can run through all of them recursively like that:
extension UIView
{
func allSubViews() -> [UIView] {
var all: [UIView] = []
func getSubview(view: UIView) {
all.append(view)
guard view.subviews.count > 0 else { return }
view.subviews.forEach{ getSubview(view: $0) }
}
getSubview(view: self)
return all
}
}
// Call this method when all views in your parent view were set
func disableMultipleTouching() {
self.isMultipleTouchEnabled = false
self.allSubViews().forEach { $0.isExclusiveTouch = true }
}

Store previous value from stepper in swift

The logic from here Stepper value reset after loaded from coredate doesn't work with me plus its in obj C.
I have a label and stepper, i need the value in the label to act as a counter almost. Currently, when i close and reopen the views the core data works and the value from before shows in the label, but when i tap the stepper (after coming back to the view with the stepper) the value in the label counts from 0 again, i need it to add on to the previous value!
This must be easy but i can't seem to figure it out!
Thanks for any help in advance
#IBAction func stepperTapped(sender: UIStepper) { // when the user taps the stepper
label.text = String(Int(sender.value))
someObject.theCounterProperty = Int(sender.value)
do {
try context!.save()
} catch {
print("error")
}
}
Make sure the label and the counter are up to date when the view reappears. In viewWillAppear set the value from the Core Data object.
label.text = String(someObject.theCounterProperty)
counter.value = Double(someObject.theCounterProperty)

(swift) Anyone can help me to make bulk change to those buttons?

here is the screenshot
when user get into this page, I want to change the background of those button.
for example, when the level of user is 6, I want to change the top 6 background of buttons to a blue picture as first button. I don't wanna write a code one by one, so please help me to write a function, Thank you very much!
You can add you buttons to the array in order of increasing level and do something like this:
var buttons: [UIButton] // array of your buttons, next you need to init it
...
func setColorForUserLevel(userLevel: Int) {
if userLevel > buttons.count {
return
} else {
for i in 0...userLevel - 1 {
buttons[i].backgroundColor = UIColor.blueColor()
}
}
}
I create simple example project to show how to use it:
I have outlets with UIButton! type and buttons object in code:
And i test setColorForUserLevel function in viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
buttons = [button1, button2, button3]
setColorForUserLevel(2)
}