Prevent TableView from scrolling when sidebar is active - ios

I have a sidebar in an UITableView which will display after a long press on a cell. The sidebar has some custom buttons for more functionality.
If the user tab on the UITableView, I will check for the location of the point. If it is outside of the sidebar, then I will close it.
The problem here is, if the user try to scroll (its about 100 rows here) the sidebar stays on the exact place. So my goal is to prevent the user from scrolling on the table as long the sideview is present. (I will also highlight the selected row later.)
I created a UIGestureRecognizer:
tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
view.addGestureRecognizer(tapGesture!)
And check the location:
func handleTap(recognizer: UITapGestureRecognizer){
let location = recognizer.locationInView(view)
if !CGRectContainsPoint(contentView.frame, location){
// dismiss
}
I have a delegate which shows me if the sideview is present, but if I try to set:
tableView.userInteractionEnabled = false
I am unable to click on the sideview, so all user interactions are disabled.
Is there a way to disable only scrolling?

So simple just write this
tableView.scrollEnabled = NO;

Related

Is it possible to disable didSelectRowAtIndexPath in a part of row in UITableView?

I have a UITablaView in my Objective C application. I have the custom cells with a label and a UIImageView. I want to disable a part of the rows, to disable didSelectRowAtIndexPath when users click on this row's part.
I want this:
Is it possible?
Here is the simple and the most elegant solution that I can think off.
I believe you must be having a CustomCell, which holds the IBOutlet to imageView on the left side :) You can make use of hitTest method to solve your problem :)
In your CustomCell lets assume it to be MyTestCell class write this,
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.myImageView.frame.contains(point) {
return nil
}
return super.hitTest(point, with: event)
}
Where myImageView is the IBOulet of imageView on the left hand side of your cell :)
All am doing is checking where did user tap, if the touch point is within the frame of cells imageView you return nil as the view. When you return nil touch event stops propagating to its parent views and finally will never reach cell hence didSelectRowAtIndexPath never called,
On the other hand you should handover touch to the next view and you do it simply by calling same method on its super iOS will eventually trace it back to cell and triggers didSelectRowAtIndexPath
Hope it helps :)
You can do a simple trick (without the need of writing code) to solve this issue, by adding a button that covers the part that you want to disable the selection of it. Obviously, the button should not have any text or background color (it should be clear color), also make sure to add suitable constraints for making sure that is covered the wanted part of the cell.
So when tapping on the button, nothing should happen and didselectRow should not get called because the actual touching event should be referred to the button, not to the row.
Hope this helped.
This is very simple trick,
Add a button on profile image part, means on red part as shown in picture (provided by you). And don't do on click on button click.
Happy Coding!!!!
Simply put the button over Green area and set tag for each button. Onclick you can perform your functionality using tag. Like this
inside
func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let obj: AnyObject = self.dataList.objectAtIndex(indexPath.row);
cell?.populateCellWithData(obj, indexPath: indexPath)
cell?.destinationLabel.userInteractionEnabled = true
let destRecognizer : UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DestLabelTapped:")
destRecognizer.numberOfTapsRequired = 1
destRecognizer.delegate = self
cell?.destinationLabel.addGestureRecognizer(destRecognizer)
}
and in DestLabelTapped you can peform your functionlity
Another way
Just set two Tableview and scroll them side by side and one table is selectable and another is not. (don't do this)
In my understanding the tricks with buttons and other UIElements that are covering the content are not the right way to solve the target. As you will need extra manipulations with them in Storyboard, if you will need to make dynamically content, if you will work with constraints and many more situations where you will need to control your content and + the artificial cover. There are few things to do:
Set UITableView selection to No Selection
Put the second part that you want to be active in UIView. This UIView will be the content container.
Add UITapGestureRecognizer to UIView
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectCellAction:)];
Add IBAction where you could do all you need.
- (IBAction)selectCellAction:(id)sender
{
// do what you need
}
And thats all.
You may simply do change the image view width constraints to 0. Where you want to action is performed. As for example:
1) If you use a button that cover the image.
2) If you take a navigation bar then you there take a button and perform the action.
hope this will help.

UITapGesture removing ability to select from UITableView when resigning keyboard responder

So I'm having an issue where I have added a UITapGestureRecognizer to resign first responder status of associated textfields so the keyboard will drop away.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(AddMedViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
func dismissKeyboard() {
medNameText.resignFirstResponder()
doseAmountText.resignFirstResponder()
}
This works fine for getting rid of the keyboard but not when I want to make a selection from a UITableView that is embedded in the same view. (The text fields are located outside this table view).
Essentially each table view cell represents a pre created specific time that is chosen to match the text entered into the text fields then passed along all together to another view.
Any Idea how I can get the UITableView to still recognize the selection of cell when tapped while resigning first responder of the text fields?
I have tried adding a gestureRecognizer function but as I am new to Swift(and an amateur coder) I am not exaclty sure how it works. Any help would be greatly appreciated!
Thanks.
try to add tap.cancelsTouchesInView = false
It means touches are delivered to a view when a gesture is recognized.

Swift UITableView Swipe During Scroll Animation

I've looked around and tried everything I can think of sort of subclassing TableView, but I think I'm missing something. I have a TableView with entries that I can swipe left and right on, and everything works fine. However, if:
1) I start (vertically) scrolling a little bit, and then swipe, the TableView's superclass, ScrollView, seems to block the swipe from my TableViewCell.
2) I stop scrolling, but the animation hasn't fully stopped, the swipe is still blocked from the TableViewCell.
How can I allow my swipe to get passed through to my TableViewCell, regardless of the vertical scroll?
Swift 2.2, Xcode 7.3
I fixed this basically by doing what was suggested in this thread: Tell ScrollView to Scroll after other pan gesture
Below is code that should enable someone else that comes across this thread to scroll in a table view, and be able to swipe, without having to deal with the table view's pan gesture recognizer blocking the swipe due to the mere hint of vertical motion.
Hope it helps someone.
So (inside a UITableViewController -- non--essential code emitted):
var lsgr : UISwipeGestureRecognizer!
override func viewDidLoad(){
super.viewDidLoad()
self.lsgr = UISwipeGestureRecognizer(target: self, action: "didSwipeLeft:")
self.lsgr.direction = .Left
self.lsgr.cancelsTouchesInView = false
self.lsgr.delegate = self
}
func didSwipeLeft(leftSwipe: UISwipeGestureRecognizer){
var ip = self.tableView.indexPathForRowAtPoint(leftSwipe.locationOfTouch(0,inView: self.tableView))
print("swipe left - "+String(ip!.row))
}

Sliding tableViews (much like calendar)

What do you recommend would be the best way to create the sliding tableView effect seen in calendar, where you can "swipe" between tableViews?
Currently, the way I have it working is detecting swipe gestures, and then reloading 1 tableView based on the swipe direction. While this works, it doesn't look all that great. I really want the effect where as they drag right/left the next tableView is dragged in.
var rightRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipeFrom:")
rightRecognizer.direction = .Right
var leftRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipeFrom:")
leftRecognizer.direction = .Left
self.view.addGestureRecognizer(rightRecognizer)
self.view.addGestureRecognizer(leftRecognizer)
func handleSwipeFrom(gesture: UIGestureRecognizer) {
println(previousDays.count)
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.Right:
//call function to get new data
self.tableView.reloadData()
case UISwipeGestureRecognizerDirection.Left:
//call function to get new data
self.tableView.reloadData()
}
default:
break
}
}
}
To achieve this , instead of using TableView, you can use UICollectionView.
Please refer following reference links to implement UICollectionView;
1) Link 1
2) Link 2
3) Link 3
Hope this will help.
What I have done in the past is create a UIScrollView that will scroll horizontally and add each TableView inside of that side by side. You can then set the pagingEnabled property to yes so that when you scroll horizontally the scrollView will snap to show only one tableView at a time.
It is really quite fluid and simple to implement.
You should use collection view and in each collection view cell contains tableview. you can also use scrollview but in scrollview you have to manage content-size and other thing and scrollview don't deallocate memory after scrolling while in collection view only load current cell memory.

Unslide Delete Button UiTableViewCell

In my app, you can slide to delete a row as done here. After sliding, an alert pops up confirming the deletion. If you cancel it, I'd like to slide the row over so that the delete button is no longer visible. Right now I'm doing the following, but there's got to be a better way that looks more fluid.
self.tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation:UITableViewRowAnimation.Right)
disable edit mode on the tableView
objC: self.tableView.editing = NO;
swift: self.tableView.editing = false

Resources