insertSublayer will hide cells in table view - ios

This code works in iOS7, but when running in iOS6 simulator the cells who should be above the sublayer will instead be below them.
bgLayer = [BackgroundLayer gradientFromColor:COLOR_MID_GRADIENT to:COLOR_GRADIENT];
CGRect bottom = self.view.bounds;
bottom.origin.y = self.view.bounds.size.height-GRADIENT_HEIGHT;
bottom.size.height = GRADIENT_HEIGHT;
bgLayer.frame = bottom;
[self.view.layer insertSublayer:bgLayer atIndex:1];
What it does is to put a gradient-layer at the bottom of a view with a tableview.
However, the cells in the rect of the gradient will be hidden behind it!
I tried to change the index but it doesnt do anything. Also, insertSublayer: below: doesn't work either.
What am I missing? How to put the layer below the table view cells?
Thanks.

Thanks to trojanfoe I got pointed in the right direction.
I've managed to get it working with manually changing the zPosition for the conflicting layers. Though I have to run the add layer-code in viewDidAppear instead of viewWillAppear for iOS6. Don't ask me why, I guess it has to do with the rendering of the cells happening after viewWillAppear.

You mean below, as in "behind"? If so, set the backgroundView of the tableview , and modify it as you see fit. (layers, subvies etc) and it will always appear behind the cells

Related

iOS how to make subview of a transparent view opaque?

I have a view as the subview of another view, then I set the alpha value of the father view something like 0.5, but this also makes the subview transparent even when its alpha value is set to 1. So how can I make the subview non-transparent(opaque) when its father view has an alpha value less than 1?
The closest you're going to get is colorWithAlphaComponent:. Using something like the following, you can set the alpha component of the parent view's background, and it won't affect subviews.
[yourSuperview setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.5]];
If you set the parent view to 0.5 all the subviews will also go to 0.5 or less. You'll have to come up with a different design approach.
For Swift 4.2
self.yoursuperview.backgroundColor = UIColor.black.withAlphaComponent(0.5)
The following method worked for me.
superView.backgroundColor = .clear
Now that alpha property of superview is not altered, it won't affect the alpha of its subview. Hence, subviews will be opaque(if you have a background color for it).
You should have two designs for the parent view. One would be the "enabled" design, showing it as it is and the other would be the "disabled" design, which would contain transparent background.
You cannot do this with alpha, as subviews inherit the alpha. If
parent.alpha = x
and
view.alpha = y,
then the real alpha of the view will be:
x * y
I think, You have create View by Storyboard. I had already face this problem. Find the below code, this is correct in my case.
[MyParentView setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.6]];
Hope, This may help you.

Bounds automatically changes on UIScrollView with content insets

I'm using a UIScrollView as my paging scroll view, pagesScrollView. Inside that, I put individual UIScrollViews which are used exclusively for zooming. Inside each of those, I have one view which is the page item which should be zoomable. All of that is inside a UINavigationController with a translucent navbar.
My pagesScrollView has contentInset.top = 64 and bounds.origin.y = -64 (that seems weird to me, but that's what the system is setting automatically for me), and this works just fine. My screen looks great!
However, after I scroll the pagesScrollView even a tiny bit, as soon as scrollViewWillEndDragging is called, the pagesScrollView begins an animated change from bounds.origin.y = -64 to bounds.origin.y = 0 which causes my page items to be obscured by the navbar.
On the left is what it looks like when it loads, on the right is what it looks like after I drag just a few pixels and then let go, it slides up under the navbar (because the bounds.origin.y goes to 0).
The problem is that I don't have any code that is altering the bounds and I don't have any code in the various scroll delegate methods that do anything. I've added a bunch of scroll delegate methods and just added NSLog()s so I can figure out when/where the change is happening, but it's not happening anywhere in my code.
So, I don't know what code I can show you to help you help me.
EDIT: I built a new project from scratch to remove all other variables.. I put a bare UIViewController into a UINavigationController. I put a UIScrollView into my View the entire size of the view. The following code is the entire project.
It turns out the issue (described below) only appears once PAGING IS ENABLED on the UIScrollView! Wtf? :)
Here is a link to download a basic project with only a few lines of code which demonstrates the problem. Just click in the scrollview and you'll see it shift up as the bounds change. http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip
How can I have paging enabled on my scrollview without the bounds freaking out during scrolling and shifting everything under the nav bar?
It's possible to set the navbar to opaque and the problem is avoided, but the ideal is to have standard iOS7 behavior so that after the content view is zoomed, THEN the content is allowed to be under the navbar and should show through the translucency normally.
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSArray *colors = #[
[UIColor blueColor],
[UIColor orangeColor],
[UIColor magentaColor],
];
NSArray *zoomerColors = #[
[UIColor greenColor],
[UIColor yellowColor],
[UIColor purpleColor],
];
self.scroller.pagingEnabled = YES;
[self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)];
CGRect subviewFrame = CGRectMake(0, 0, 160, 240);
for (int index=0; index < colors.count; index++) {
UIColor *color = [colors objectAtIndex:index];
UIColor *zoomerColor = [zoomerColors objectAtIndex:index];
UIView *subview = [[UIView alloc] initWithFrame:subviewFrame];
subview.backgroundColor = color;
CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height);
UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame];
[zoomer addSubview:subview];
zoomer.backgroundColor = zoomerColor;
[self.scroller addSubview:zoomer];
}
}
Just switch off Adjust Scroll View Insets
It's an iOS bug. I created the following subclass of UIScrollView to get a log of what happens to y over time and who was pushing it:
#implementation CSScrollView
- (void)setContentOffset:(CGPoint)contentOffset
{
NSLog(#"%0.0f %#", contentOffset.y, [NSThread callStackSymbols]);
NSLog(#"[%#]", self.layer.animationKeys);
[super setContentOffset:contentOffset];
}
#end
(and changed the view class in the storyboard)
When you release your finger, a method called UIScrollView _smoothScrollDisplayLink: starts animating the scroll view to its final position. As per the second log, there's no CAAnimation involved, the scroll view uses its own display link to do its own transition. That custom code appears to make the mistake of animating from y = whatever to y = 0, failing to take the content offset into account.
As a proof-of-concept hack I changed the code to:
#implementation CSScrollView
- (void)setContentOffset:(CGPoint)contentOffset
{
contentOffset.y = -64.0f;
[super setContentOffset:contentOffset];
}
#end
And, unsurprisingly, the problem went away.
You probably don't want to hard code the -64.0f but I'd conclude:
it's an iOS bug;
work around it by rejecting nonsensical values via a subclass of UIScrollView with a suitable custom implementation of - setContentOffset:.
A sensible generic means might be to check the state of self.panGestureRecognizer — that'll allow you to differentiate between scrolls the user is responsible for and other scrolls without relying on any undocumented API or complicated capturing of delegate events. Then if necessary crib the correct contentOffset.y from the current value rather than hardcoding it.
My pagesScrollView has contentInset.top = 64 and bounds.origin.y = -64 (that seems weird to me, but that's what the system is setting automatically for me), and this works just fine. My screen looks great!
It because of iOS 7 sets contentInset.top to 64 on all scrollviews.
Just add this line of code into your view controller and all will work as expected:
-(UIRectEdge)edgesForExtendedLayout {
return UIRectEdgeNone;
}
I checked on your example project.
I have checked you example use below code in viewController.m file
-(void)viewDidLoad
{
if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}
It's working fine...
It turns out the issue (described below) only appears once PAGING IS ENABLED on the UIScrollView! Wtf? :)
As you said that, If you enable the scroll paging, the UIScrollView will stop at a paging edge after a dragging or any movement, which is promised by the framework. Bounds.origin.y set by zero means that the first page edge matched the scroll view frame edge, cuz you have 64 contentInsets there. So that's not bug, that is what it is. And since your bar is translucent, remember where is your scroll view's frame edge, it's under the bar. In a word, this is not a bug, I think, but a effect of scroll paging.

IOS searchBar - Getting rid of the white space below

I have a view which has two containers: Top_Container and Bottom_Container.
Each Container points to a VC with a TableView.
The Bottom_Container points to a TableView with a searchBar on top.
Whenever the searchBar gets activated in the TableView a white space appears below the searchBar between the searchBar and the greyed zone corresponding to the serachBarTableView (which superposes the TableView).
I have been trying with no success to get rid of this white space with no success.
Anybody has an idea how to customize:
- the white space which appears below the searchBar ?
- the greyed zone (searchBar TableView ?) on top of the TableView which appears whenever the searchBar gets active ?
Thank you.
Try with following code:
CGRect rect = self.searchBar.frame;
UIView *lineView = [[UIView alloc]initWithFrame:CGRectMake(0, rect.size.height-2,rect.size.width, 2)];
lineView.backgroundColor = [UIColor clearColor];
[self.searchBar addSubview:lineView];
It is fix.
I had similar problem and in my case it was caused by opaque NavigationBar. When I set NavigationBar to translucent, then the underlaying UITableView is correctly aligned to the active UISearchBar. (note: I'm using UISearchDisplayController in my view controller)
In your case maybe you can move (and animate) the underlaying table view in UISearchDisplayDelegate's methods willBeginSearch and willEndSearch. If you are using UISearchBar only, then you need to subclass it and override becomeFirstResponder and resignFirstResponder methods and implement the "table view moving" code there.
I just fixed this problem in my own code. For me, the issue was caused by 2 lines of code.
self.viewController.edgesForExtendedLayout = UIRectEdgeNone;
self.navigationBar.translucent = NO;
After removing both these lines, everything worked as expected.

iOS 7 Custom TableView Is Under TabBar

Im trying port my app to iOS7, but my custom TableViewController is showing the last row (cell) under the TabBar :(
Im searching a lot for it, but i dont find any solution. Can anyone help me?
My Custom Table View class
The error is shown in the blow screenshot (only is showing a part of last product because im draging to up to show the hidden product under the tabbar):
Thanks.
I've got the same problem and solved it using storyboard.
At Tab Bar Controller, go to attribute inspector, Simulated Metrics, and set the Bottom Bar to Opaque Tab Bar. That's it!
See image bellow for description.
Saudações! (Greetings!)
I found the answer to your question on another post, answered by dariaa, here:
Tab Bar covers TableView cells in iOS7
It worked great for me.
Please no credit for me, because I'm not the original guy who solved it.
In your custom TableViewController, add these two lines under [super viewDidLoad]:
- (void)viewDidLoad
{
[super viewDidLoad];
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0., 0., CGRectGetHeight(self.tabBarController.tabBar.frame), 0);
}
My friends, I cannot tell you how badly I struggled from this. Not a single re-configuration of Story Board never helped me. The issue was exactly like in Original Post, I've managed to fix it using:
for swift 3
self.edgesForExtendedLayout = []
for objective-c
self.edgesForExtendedLayout = NO;
2 lines in viewDidLoad and that's it !
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableview.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
In iOS 7 viewController uses full height. There is a property introduced as
self.automaticallyAdjustsScrollViewInsets = NO;
set it to no. then check, or set UIEdgeInset if is not set right after it.
UIEdgeInsetsMake(top, left, bottom, right)
See here
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html
Edit: try also this
self.edgesForExtendedLayout = UIRectEdgeNone;
The root cause of this problem is that automaticallyAdjustsScrollViewInsets is effective only on the First scroll view in your VC's view Hierarchy. It is not documented by Apple, but it is the only way the VC will detect the scroll view needing to be modified unless you're using a UITableViewController.
So in order to fix your issue without manually adjusting the insets, do this:
Make sure "Adjust Scroll View Insets" is checked.
Make sure that the tableView is the first subview in the view Hierarchy.
(Move it upwards above all other elements)
UIViewController has two new properties to assist you : topLayoutGuide and bottomLayoutGuide. They return the height of the parent view controller's controls you need to avoid. In this case, bottomLayoutGuide will return the offset of the tab bar.
Your custom view controller is probably overriding a method and not invoking super's implementation where this would be done for you. I am guessing you are installing AutoLayout constraints or setting a view's frame manually to fill the view. You just need to include the value from [bottomLayoutGuide length] to your layout calculation. If you support rotation, you should update that value in willAnimateRotationToInterfaceOrientation:duration:.
UINavigationController and UITabBarController both have a transparency flag that can be set programmatically or in the storyboard.
The UINavigationController also has two flags that control if the content extends under the top or bottom bar. Again you can set them programmatically or in the storyboard. This will apply to all subviews.
Each UIViewController can set its own preference in code. The property is called edgesForExtendedLayout and you can set up all combinations.
Using those properties will allow AutoLayout and Springs'n'Struts to adjust the views the way you want them regardless of the device.
There are a lot more new properties in UIViewController that you will want to have a look at.
Try the following:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeBottom;
I've got the same problem. One solution to it is to make the ToolBar not Translucent. Here's how to do it:
First select the tool bar from the document viewer
like here
Then uncheck Translucent like here
Hope this helps.
Thanks.
The problem was masked using:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 112, 0);
}
But it doesn't solve, because on each iPhone and on each app tableview i have a different space on bottom.
So this is a poor solution.
I dont know a way to solve it.
I solved my problem now, changing my BaseTableViewController to inherit from UIViewController to UITableViewController.
But using a TableView inside a UIViewController is not solved :(
Thanks.
maybe is not a right answer, also for that reason I post this answer so you can tell me if this answer could be a possible solution.
In my case, I like the translucent effect, so I have added a footer in the table and I have modified the scrollIndicators.
- (void)viewDidLoad
{
// Do any additional setup after loading the view.
[super viewDidLoad];
UIView *footer = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.agendaItemsTable.frame.size.width, self.tabBarController.tabBar.frame.size.height)];
self.agendaItemsTable.tableFooterView = footer;
self.agendaItemsTable.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, self.tabBarController.tabBar.frame.size.height, 0);
}
What do you think?
I had the same problem, and the up-voted answers did not solve it. See my answer to a similar question, Tab Bar covers TableView cells in iOS7.
I solved the issue by manually setting the table view's frame in the table view controller's viewWillAppear: method to the height of the screen - (status bar height + nav bar height + tab bar height).
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Adjust height of tableview (does not resize correctly in iOS 7)
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = [self heightForTableView];
self.tableView.frame = tableViewFrame;
}
- (CGFloat)heightForTableView
{
return CGRectGetHeight([[UIScreen mainScreen] bounds]) -
(CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]) +
CGRectGetHeight(self.navigationController.navigationBar.frame) +
CGRectGetHeight(self.tabBarController.tabBar.frame));
}
If anyone finds a better solution to this problem, please share!
For those like xarly who want the translucent effect, and for an Autolayout solution (without setting frames), see my answer here https://stackoverflow.com/a/26419986/1158074
I had a similar problem with collection view. Changing the collection view frame and content inset below fixed it for me...
guard let cv = collectionView,
let tabBar = tabBarController?.tabBar else { return }
// Resize collection view for tab bar
let adjustedFrame = CGRect(origin: cv.frame.origin,
size: CGSize(width: cv.frame.width, height: cv.frame.height - tabBar.frame.height))
cv.frame = adjustedFrame
// Adjust content inset for tab bar
let adjustedContentInsets = UIEdgeInsetsMake(0, 0, tabBar.frame.height, 0)
cv.contentInset = adjustedContentInsets
cv.scrollIndicatorInsets = adjustedContentInsets
Good luck!

Strange border in UITableView

I'm getting an odd behaviour with UITableView that maybe someone can help me with.
I have a UITableView. I then do:
table.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tablebg.png"]];
cell.backgroundColor = [UIColor clearColor];
This works as expected, except I'm getting a strange white border along the right and bottom of the table (see image).
Any ideas?
Seems like the tableview isn't aligned with the very superview (view) edge. Make it a bit wider and taller. I would temporarily set the view background color to something else so that you can see where the table extends to.
It seems that your are using a PNG with alpha different from 0 and I have experimented the same issue with some images. Try:
table.backgroundView.alpha = 1.

Resources