Bringing a subview in a UITableViewCell to front - uitableview

I added a bunch of UILabel views to a UITableViewCell's contentView, some of which may overlap. On tapping any of the labels, I want to trigger some actions. Also, I want to bring up the tapped label to the top.
Using a UITapGestureRecognizer on the labels, I can figure out which one is tapped and perform the actions. But bringing the tapped and overlapped label to the front does not work. This is what I am trying:
UILabel *foundLabel = ....; // find the label
for (UITableViewCell *acell in theTable.visibleCells) {
UIView *cellContentView = acell.contentView;
if ([cellContentView.subviews containsObject:foundLabel]) {
[cellContentView bringSubviewToFront:foundLabel];
NSLog(#"should bring to front...");
}
}
I do get the NSLog output above, so I know that the bringSubviewToFront is being called on the appropriate cell's contentView. But no change in the subview layout order.
Ideas?

One thing to explore is zposition on the uitablviewcell's layer.
This successfully put on tableviewcell in front of another for me:
cell1.layer.zPosition=3 ;//above
cell2.layer.zPosition=2 ;//below

bringSubviewToFront: didn't work for me either
Try insertSubview:belowSubview: where the latter subview is a super view such as tab bar, nav bar, table view.

Related

UIView stuck behind UITableview header

In my app I have a UITableViewCell with a UITextField in it. When the user starts typing in this textfield, an autocomplete view appears.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if (self.suggestions != nil) {
self.autocomplete = [[AutoComplete alloc] initWithFrame:CGRectMake(10, 53, self.frame.size.width-20, 200)];
self.autocomplete.delegate = self;
self.autocomplete.suggestions = self.suggestions;
[self addSubview:self.autocomplete];
[self bringSubviewToFront:self.autocomplete];
}
return YES;
}
This is nothing more than a UIView with a UITableView inside it. However, what happens is that this view is hidden behind the section header and the next cell.
So while it appears to be inserted above the cell, it registers the tapp below it. When you click in the autocomplete it registers the click in the next cell. How can I fix this?
Your issue is you are adding it to the view and not the tableview which resides in the UIView as well as having a section header that will probably block it out as well. I see your y position is only 53, so your header is likely blocking it out.
I am not 100% sure where you want your result to be viewed and used, that's not clear in your question. If you want your view to be above everything else you could:
"I have a UITableViewCell with a UITextField in it. When the user starts typing in this textfield, an autocomplete view appears." - add the result view to your cell, not the main view; [cell.contentView addSubview...
Shift your tableview down by changing it's y position to self.autocomplete.view.frame.size.height. Add a nice little animation to it as it changes position too, always something that bit extra.
Consider adding it as a subview to your TableView and bringing to front, should work.
(little bit extra on the cell.contentView)

Attaching UIButton on top of UIScrollView or UITableView

What is the best approach for attaching a UIButton on top of UIScrollView or UITableView so when the view is scrolled, the button stays in its place.
Here examples below:
UIButton stays in the right bottom corner when the view is scrolled.
google+ app example
yahoo mail app example
I think this should work. Lay Out your button in a view that is outside of the tableviewcontroller. Then drag an outlet to the tableviewcontroller file. Then add it in code. This code would hold it at the top of the screen.
#IBOutlet var buttonView: UIView!
override func viewDidLayoutSubviews() {
self.view.addSubview(buttonView)
}
override func scrollViewDidScroll(scrollView: UIScrollView) {
var rect = self.buttonView.frame
rect.origin.y = max(0,scrollView.contentOffset.y + scrollView.contentInset.top)
self.buttonView.frame = rect
}
Thank you all for great answers!
I got it worked through storyboard by moving the button from scrollView to View itself. That way it's attached on UIView and it's independent of scrollview.
storyboard snapshot
So now the structure is:
- View
- ScrollView
- Button
Before it was:
- View
- ScrollView
- Button
There are many ways to go about doing this but two that I use most often are as follows.
One approach is embedding the view controller within a navigation controller. This will set a bar on the top and bottom if you choose that you can place bar button items upon.
Another approach is to place a UIView along the top and snap the constraints to the left, right, and top with 0 no-margin. Then set the height. I usually use 40px for the height but you can use what is applicable to your needs. After that you can place a button in that UIView and then set constraints on it to keep in in place.
In my experience, this isn't reliably possible to do with the scrollView itself.
My solution is usually to put anything that needs to float above the tableView/scrollView in a plain ViewController that also contains the tableView/scrollView parent.
If you're using storyboards with a UITableViewController scene, this will likely mean you need to use another scene with UIViewController with a container that has your UITableViewController.
For UITableView use tableHeaderView. For UIScrollView you need to create a separate view not in the scroll view's hierarchy.
Another solution is to put your UIButton in a UIToolbar, and then make the toolbar a child of the UINavigationController's view. After that, in viewDidLayoutSubviews, you can set the rect of the toolbar to sit just below the navigation bar and offset the top of the UIScrollView or UITableView.
Add button which you want in the storyboard.
Design your scrollview
self.view.sendSubviewToBack(scrollViewObj)(in the code)
This worked for me.

Empty white space above UITableView inside a UIView

I'm trying to position a TableView inside my ViewController view but leaving a 44 height gap between the bottom of the navigation bar and the top of the table. I then wanted to place a UITextField inside that gap to act as a stationary header. For some reason, the TableView has an empty white space above the start of the "Prototype Cells". Its just white space. Here is what it looks like in the storyboard.
When viewing the app display, this is what it looks like:
When scrolling the table, it goes all the way up to the correct place:
Try to look in the 'attribute inspector' (in the right menu) of the Participants ViewController.
Check for the option 'Extend Edges' and uncheck the 'Under Top Bars', and then relocate your tableview.
Another possible solution is to just uncheck the option 'Adjust Scroll View Insets'.
The reason is that when the viewController extends its edges, let's say under the top bar, the tableView's scrollView automatically adjusts its inset top, so that the content of the tableView will start exactly under the top bar. But in your case this is not needed, since your tableView itself starts under the bar.
Focus on the ViewController and got to the Attribute Inspector tab:
Try this one:
self.tableView.contentInset = UIEdgeInsetsMake(-65, 0, 0, 0)
Just add this in you ViewDidLoad method
self.automaticallyAdjustsScrollViewInsets = NO;
change your table view style from grouped to plain
You should not need to change the default setting for Extend Edges.
Looks like the real problem is a blank table header view in your storyboard. It's showing in the screenshot you provided of your storyboard, right below the Enter Name view and right above the Prototype Cells view. Delete it.
My issues is, I set tableHeaderView as new UIView like this
self.tableHeaderView = UIView(frame: .zero)
Remove this line, the issue is gone. Try this:
//self.tableHeaderView = UIView(frame: .zero)
This is the 2022, iOS 15 solution if anyone stumbles upon this.
if #available(iOS 15.0, *) {
UITableView.appearance().sectionHeaderTopPadding = CGFloat(0)
}
I just found a solution for this.
In my case, i was using TabBarViewController, A just uncheck the option 'Adjust Scroll View Insets'. Issues goes away.
https://i.stack.imgur.com/qgQI8.png
For Objective-C folks, add this in your ViewDidLoad method.
[self.tableView setContentInset:UIEdgeInsetsMake(-20, 0, 0, 0)];

How do I position UITableView programmatically while using iOS7's UINavigationBar?

I have a quite regular UIViewController that is a part of a UINavigationController-hierarchy, which naturally makes the view have a UINavigationBar at the top. As we all know, iOS7's navigation bars are very different from previous versions.
If I drag a UITableView into my view in Storyboard, then the 'frame' for the table view is covering the entire view (I.E [tableView setFrame:self.view.frame];). Even behind the NavigationBar.
This makes so that if I scroll, the content will be faintly visible through the bar.
Contrary to most people, I actually like this.
In my current view controller, I would like to create the UITableView programmatically and place it as a subview here. However, I am unable to achieve the same effect this way.
I have tried
UITableView *table = [[UITableView alloc] initWithFrame:self.view.frame];
[self.view addSubview: table];
This makes the 'top scrolling point' stay behind the navigation bar. Imagine a single cell in a tableView, and it's faintly visible through the top bar. If I scroll down, it pops right up behind it. That's the default 'top position'.
I have also tried
CGRect frame = CGRectMake(0, 'nav.y+nav.height', self...width, self...height-y);
UITableView *table = [[UITableView alloc] initWithFrame:frame];
[self.view addSubview: table];
to simply place the table view in the rect below the UINavigationBar, but then I won't get the scrolling transparency effect behind the bar.
I also tried the first example along with this:
[tableView setContentOffset:CGPointMake(0, 'below navbar')];
which makes it stay exactly where I want it to stay, but as soon as I touch it (scroll and release), it scrolls back up behind the navigation bar, and stays there.
What's the programmatic solution to achieve this effect? Do I have to set the offset every time I scroll too far up, or is there a simpler solution? Along with this iOS7-style, I'd imagine they would add something like [tableView setVisibleFrame:] or something..?
Add the table in storyboard like normal but make sure you have it connected to an outlet (we will call it _tableView for now).
Then in your view controller's -viewDidLoad set the top inset to be the status bar plus the navigation bar:
`self.tableView.contentInset = UIEdgeInsetsMake( (self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height), 0, 0, 0);'
This will make sure that all of the cells will be visible but will also fill the area behind the navigation bar with white so the bar doesn't end up gray.

UITableView delete button overlaps to content

I'm preparing a UITableView with a custom prototype cell having a UISwitch widget on the right side, and I'd like to let my users be able to delete rows.
Everything is fine with that, except the fact that when the delete button shows up it overlaps to the UISwitch, this way:
Is it possible to have the UISwitch shifting left when the delete button appears?
Epilogue
I've decided for brevity to not shift my UISwitch position when "delete" button appears, but to make it disappear, bringing it back when the "delete" button is gone.
So, according to #geo suggestion (thank you), I've managed it out (quite simply) this way:
In my UITableViewCell' subclass .m file:
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if (state & UITableViewCellStateShowingDeleteConfirmationMask) {
activationSwitch.hidden = YES;
}
else {
activationSwitch.hidden = NO;
}
}
I hit a very similar problem and fixed it. You need the right autoresizing mask (assuming not doing auto layout here) for your UI elements in your custom tableview cell in Interface Builder.
In my case, I needed to add the Left constraint (see that little autoresizing picture/animation in the Size Inspector, View section) for each of my UI elements.
Add a Left "bar", and you should be good.
Override the Methode
-(void)willTransitionToState:(UITableViewCellStateMask)state
-> UITableViewCellStateShowingDeleteConfirmationMask
of your custom Cell and do there your customizing :)

Resources