sendSubviewToBack on UITableView not working properly in iOS 11 - objective-c

I have an UITableViewController to which I successfully applied in the past a gradient background, by sending the newly added subview to back:
//performed on viewDidLoad
UIView *bgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1.5*280, 1.5*SCREEN_HEIGHT)];
bgView.backgroundColor = [UIColor yellowColor];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = bgView.bounds;
gradient.startPoint = CGPointMake(0, 0);
gradient.endPoint = CGPointMake(1, 1);
UIColor *topColor = UIColorFromRGB(0x229f80);
UIColor *bottomColor = UIColorFromRGB(0x621ad9);
gradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];
[bgView.layer insertSublayer:gradient atIndex:0];
[self.view addSubview:bgView];
[self.view sendSubviewToBack:bgView];
bgView = nil;
However, this no longer works in iOS 11 and the bgView is actually placed on top of all the cells.
Anyone knows how I can fix this?
Or maybe I was doing it wrong all the time?

If your cells are transparent then you can try self.tableView.backgroundView = bgView;

If you don't need the background view to be scrolling together with the table view, you can use
self.tableView.backgroundView = bgView;
If you need the background view to be scrolling, change layer's zPosition to a negative value to make it work in iOS 11:
[self.view insertSubview:bgView atIndex:0];
bgView.userInteractionEnabled = NO;
bgView.layer.zPosition = -1;

Another way to fix it is to call [self.view sendSubviewToBack:bgView]; in tableView:willDisplayCell:forRowAtIndexPath:
It works for not transparent cells also.

it appears that addSubview(UIView) sendSubview(toBack: UIView) no longer works for UITableViewControllers in iOS11. So I swap to this:
// in ViewDidLoad
// set the backgroundImage
let backgroundImage = UIImageView(frame: self.view.bounds)
backgroundImage.image = UIImage(named: "background.png")
// self.view.addSubview(backgroundImage) // NO LONGER WORKS
// self.view.sendSubview(toBack: backgroundImage) // NO LONGER WORKS
self.tableView.backgroundView = backgroundImage

Related

IOS7 UITableView grouped like in Settings App

In IOS7 the UITableView does not have indentation anymore when using style=grouped. How can enable the indentation, so that the UITableView behaves like the settings app from apple?
There is a much simpler way to achieve this.
Place your UITableView away from the sides. eg: using Autolayout you'd have a leading and trailing space of 15px (or whatever you want). You're now creating the 'indentation' that Apple used to give you for free with grouped table views.
Adjust the layer to add corners and a border.
[[[self tableView] layer] setCornerRadius:5.0f];
[[[self tableView] layer] setBorderWidth:0.5f];
[[[self tableView] layer] setBorderColor:[[UIColor redColor] CGColor]];
(I can't post an image of the result because I don't yet have enough reputation)
An answer is located here, if you still looking for a solution,
http://i-phone-dev.blogspot.no/2014/04/keep-ios-6-uitableview-styles-in-ios-7.html
Inside cellForRowAtIndexPath method, try this:
CALayer *sublayer = [CALayer layer];
UIImage *img = [UIImage imageNamed:#"blue_box_6dbcef.png"];
sublayer.backgroundColor = [[UIColor alloc] initWithPatternImage:img].CGColor;
sublayer.frame = CGRectMake(10,0,container.frame.size.width-20, 112);
//sublayer.cornerRadius = 5; // For rounded corners
UIView *bgview = [[UIView alloc] init];
bgview.backgroundColor = [UIColor clearColor];
[bgview.layer addSublayer:sublayer];
cell.backgroundView = bgview;
That will add a 10pt margin on both sides (left/right) of the cell.

UISlider in UIToolbar -> can't get slider.value and process it. iOS SDK

I'm trying to get a UISlider into my UIToolbar and to take the value from it and process it. I also want to be able to change the slider.value via other methods.
So, I set it up for the UISlider by it's self (not on a UIToolBar) and everything worked fine. Then, when I put it into the UIToolBar, the value stopped getting sent to and from it (I am NSLogging it whenever it changes and I keep getting 0 returned to me).
Here's the relevant section of my code - does anybody have any ideas?
- (void)setupToolBarAndSlider {
CGRect frame = CGRectMake(0.0, 0.0, 200.0, 30.0);
UISlider *slider = [[UISlider alloc] initWithFrame:frame];
[slider addTarget:self action:#selector(sliderValueChanged) forControlEvents:UIControlEventValueChanged];
[slider setBackgroundColor:[UIColor clearColor]];
slider.minimumValue = 0;
slider.maximumValue = 8;
slider.continuous = YES;
slider.value = questionNumberForArray;
//Change slider for UIToolbar
UIBarButtonItem *skipQuestionSlider = [[UIBarButtonItem alloc] initWithCustomView:slider];
// Set the width of aSlider
[skipQuestionSlider setWidth:400.0];
//Set up UIToolBar with Slider in it.
UIToolbar *toolBar;
CGRect rect2 = CGRectMake(0, toolBar.frame.origin.y , self.view.frame.size.width , 44);
toolBar = [[UIToolbar alloc]initWithFrame:rect2];
toolBar.barStyle = UIBarStyleBlackTranslucent;
[toolBar setItems:[NSArray arrayWithObjects:skipQuestionSlider, nil]];
[self.view addSubview:toolBar];
}
- (void)sliderValueChanged {
NSInteger roundedSliderNumber = round(skipQuestionSlider.value);
NSLog(#"Slider Value = %d", roundedSliderNumber);
}
Sam
A UIBarButtonItem (in your case, skipQuestionSlider) does not have a value property, it just houses the item. You need to reference the item you put in the UIBarButtonItem.
NSInteger roundedSliderNumber = round(slider.value);

UINavigationController rightbarbuttonitem not showing

after going through the questions related to UINavigationController item i came to post my exact problem ..
firstly i am not add a UINavigationController in MainWindow.xib i created and adding UINavigationController in AppDelegate file
after that in a UIViewController (not in rootViewController) class I have to add a rightbarbutton of Done type I am
adding it in a searchbarDelegate Method showing as bold:-
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {
//This method is called again when the user clicks back from teh detail view.
//So the overlay is displayed on the results, which is something we do not want to happen.
if(exhibDataObj.searching)
return;
//Add the overlay view.
if(ovController == nil)
ovController = [[OverlayViewController alloc] initWithNibName:#"OverlayView" bundle:[NSBundle mainBundle]];
CGFloat yaxis = self.navigationController.navigationBar.frame.size.height;
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
//Parameters x = origion on x-axis, y = origon on y-axis.
CGRect frame = CGRectMake(0, yaxis, width, height);
ovController.view.frame = frame;
ovController.view.backgroundColor = [UIColor grayColor];
ovController.view.alpha = 0.5;
ovController.rvController = self;
[self.theTableView insertSubview:ovController.view aboveSubview:self.parentViewController.view];
exhibDataObj.searching = true;
letUserSelectRow = NO;
self.theTableView.scrollEnabled = NO;
//Add the done button.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self action:#selector(doneSearching_Clicked:)];
}
but this never works .
Any help will be more appreciable.
I've tested your code real quick and it seems to be working fine for me, however, I've had the same problem once back then it turned out I was setting the rightBarButtonItem to nil in my viewDidLoad method after setting it to a button. you should make sure your not making the same mistake somehow.
However if that does not work for you you can always try setting a custom button to it:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 5, 30, 30)];
button.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"done.png"]];
[button addTarget:self action:#selector(doneButtonClicked) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationController.visibleViewController.navigationItem.rightBarButtonItem = customItem;

iOS: Table cell footer dropshadow

I have a tableview with only a few rows. So instead of displaying a bunch of blanks I added a blank UIView to the tableview.footer. However I would like the last cell to cast a dropshadow on the UIView. How would I achieve this? Here is my current code.
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *emptyView = [[UIView alloc] initWithFrame:CGRectZero];
CALayer *layer = [emptyView layer];
[layer setShadowOffset:CGSizeMake(0, 1)];
[layer setShadowColor:[[UIColor darkGrayColor] CGColor]];
[layer setShadowRadius:8.0];
[layer setShadowOpacity:0.8];
self.tableView.tableFooterView = emptyView;
}
EDIT:
It is adding the UIView to the footer but not creating the dropshadow. I'm not sure the layer is the best approach for this or even correct for this type of thing.
It is probably because you set the frame to CGRectZero.
The zero rectangle is equivalent to CGRectMake(0,0,0,0).
A shadow of a zero rect (x=0, y=0, width=0, height=0) won't show at all.
Try giving it a proper frame size and you will see the difference.
Check out this for ref as well: https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html
I ended up using
shadowBackgroundView.layer.shadowOpacity = 0.3;
shadowBackgroundView.layer.shadowRadius = 2;
shadowBackgroundView.layer.shadowColor = [[UIColor blackColor] CGColor];
shadowBackgroundView.layer.shadowOffset = CGSizeMake(0.0, 1.0);
CGPathRef shadowPath = [UIBezierPath bezierPathWithRoundedRect: shadowBackgroundView.bounds
byRoundingCorners: UIRectCornerAllCorners
cornerRadii: CGSizeMake(PageCellBackgroundRadius, PageCellBackgroundRadius)].CGPath;
shadowBackgroundView.layer.shadowPath = shadowPath;
shadowBackgroundView.layer.shouldRasterize = YES;
[self addSubview: shadowBackgroundView];
In cellForRowAtIndexPath: function:
// drop shadow
cell.layer.shadowOpacity = 1.0;
cell.layer.shadowRadius = 1.7;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0.0, 0.0);

can't set tableview frame in landscape, parameters set but view is strange [screenshot attached]

I try to set the frame of a UITableView to (190,0,610,768) in landscape mode. The frame parameters are correctly set but display is not correct.
To contrast the result, I added a UIlabel with same frame to the bottom:
CGRect frame = CGRectMake(190, 0, 610, 768);
UILabel *lbtb = [[UILabel alloc] initWithFrame:frame];
lbtb.backgroundColor = [UIColor cyanColor];
lbtb.text = #"";
[self.view addSubview:lbtb];
dishMenuVC = [[DishMenuViewController alloc] init] ;
dishMenuVC.view.frame = frame;
dishMenuVC.view.backgroundColor = [UIColor redColor];
dishMenuVC.view.alpha = 0.5;
[self.view addSubview:dishMenuVC.view];
I found a workaround to this problem by creating a container UIView with my intended frame and add the tableview to its subview.