UITableView background does not set - ios

I have this code inside the viewDidLoad (putting that inside the viewDidAppear didn't work either).
UIView *texturedBackgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
texturedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"BackgroundLeather.png"]];
self.tableView.backgroundView = texturedBackgroundView;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
But I cannot see any background as an image. It is completely white - like no image is set. Why is that?
Please note that, my tableview has it's own controller - which is initialised like this :
AppDelegate *del = (AppDelegate*)[[UIApplication sharedApplication] delegate];
PAPHomeViewController *vc = del.homeViewController;
vc.view.frame = self.containerView.bounds;
[self.containerView addSubview:vc.view];
[self addChildViewController:vc];
So, it is like I see the background of the containerView and not the background of the tableview.
Trying that didn't help it :
[self.containerView setBackgroundColor:[UIColor clearColor]];

Related

Why is view of UINavigationController root controller smaller than nav controller

I am trying to create a transparent UINavigationBar and here is what I do:
First, I have a navVC and a general VC as root VC in my code.
SNLoginViewController *loginVC = [[SNLoginViewController alloc] init];
SNLoginNavController *loginNavVC = [[SNLoginNavController alloc] initWithRootViewController:loginVC];
[self presentViewController:loginNavVC animated:YES completion:nil];
I didn't override the init method of SNLoginViewController.
And here is the implementation of initWithRootViewController::
- (instancetype)initWithRootViewController:(UIViewController *)rootViewController {
self = [super initWithRootViewController:rootViewController];
if (self) {
UIImage *bgImage = [UIImage imageNamed:#"bg"];
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:bgImage];
bgImageView.frame = [UIScreen mainScreen].bounds;
[self.view insertSubview:bgImageView atIndex:0];
[self.navigationBar setBackgroundImage:[UIImage imageNamed:#"transparent"]//transparent is a transparent png
forBarMetrics:UIBarMetricsCompact];
self.navigationBar.shadowImage = [UIImage imageNamed:#"transparent"];
self.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[self.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName:[UIColor whiteColor], NSFontAttributeName: [UIFont systemFontOfSize:18]}];
self.navigationBar.clipsToBounds = YES;
}
return self;
}
Using these codes (setBackgroundImage:forBarMetrics:) I should have been able to make the navigation bar transparent but something went wrong. The major problem is that somehow the frame of loginVC is smaller than loginNavVC.
(source: zybuluo.com)
In the figure above the selected view is of loginVC and the one on the left is of loginNavVc. loginVC is smaller than loginNavVc.
But in viewDidLoad of loginVC I print the selected view, its frame is (0 0; 320 568) but when I print its description in view hierarchy (same address in memory), its frame is (0 64; 320 504). Why would this happen? How to make it full screen(not full screen like games, status bar should still be visiable)?
Add this before presenting your navigation controller.
[self.loginNavVC.navigationBar setBackgroundImage:[UIImage new]
forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self. loginNavVC.navigationBar.translucent = YES;

Show custom view over tab bar in iOS

I want to show custom view over tab bar. I have seen that UIAlertView shows view over UITabBar and user can't interact with tab bar when alertView is open. I tried it by showing it over the keyWindow by using the code below:
[[[UIApplication sharedApplication] keyWindow] addSubview:myViewObject];
but user can still change the tabs.
I used to do it with overlayView when I create custom controls that need to block the block whole window and show
//self refers to active UIViewController
UIView *overlay =[[UIView alloc]initWithFrame:self.view.window.rootViewController.view.bounds];
overlay.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.4];
overlay.tag = 1001;
[overlay setUserInteractionEnabled:YES];
[self.view.window.rootViewController.view addSubview:overlay];
you can add a tap gesture to remove overlayView from superview .
try this out:
UIView *coverView = [[UIView alloc] initWithFrame:self.view.frame];
coverView.backgroundColor = [UIColor greenColor];
coverView.alpha = .3f;
UIWindow *window = [[UIApplication sharedApplication] windows].lastObject;
[window addSubview:coverView];
You can set tabBarController.tabBar.userInteractionEnabled = false on the tab bar while the custom view is shown.

Adding UIView as subview of app's main window

I want to display a UIView on top of other views, no matter what view is currently displayed. So I created the following method in custom class that is not related to any views:
- (void) showLoading {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
[redView setBackgroundColor:[UIColor redColor]];
[[appDelegate window] addSubview: redView];
}
The view is not displayed when the method is called. However it is displayed if I rotate device, so screen orientation is changed. I guess that I should reload view somehow, but at this point I'm stuck. Could you please help me?
Thank you, dtrotzjr, for good question. The problem was that the method was called from background thread. Here is the solution:
dispatch_async(dispatch_get_main_queue(), ^{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
[redView setBackgroundColor:[UIColor redColor]];
[[appDelegate window] addSubview:redView];
});
Sorry for bothering.
You can create a AlertViewController and present that on top of any view controller, you can even make this AlertViewController to be transparent.
self.parentVC = someVC;/*this should be the VC over which you want to present the alert VC */
self.modalPresentationStyle = UIModalPresentationCustom;
[self setTransitioningDelegate:someDelegate];
dispatch_async(dispatch_get_main_queue(), ^{
[self.parentVC presentViewController:self
animated:YES
completion:^{
}];
});

UINavigationBar with UISegmentedControl partially covers childViews

I have read many other threads on this and the Apple docs, but haven't found a solution yet for my particular problem.
My app uses a UITabBarController as the rootViewController, and in one of the tabs I have a UISegmentedControl in the navigationBar to switch between three child UITableViewControllers.
(In the real app two of the childVCs are a custom UIViewController, I'm just using three UITableViewControllers for the sample app).
The segmentedControl setup and the switching all works fine. The thing that goes wrong is that only the first UITableViewController is shown correctly. For the second and third one, part of the first cell is hidden under the navigationBar. When I click through all three, the first one is still ok.
I have made a little sample app to show what's going on, using very bright colors for demonstration purposes: https://www.dropbox.com/s/7pfutvn5jba6rva/SegmentedControlVC.zip?dl=0
Here is also some code (I'm not using storyboards):
// AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
FirstViewController *fvc = [[FirstViewController alloc] init];
UINavigationController *firstNavigationController = [[UINavigationController alloc] initWithRootViewController: fvc];
SecondViewController *svc = [[SecondViewController alloc] init];
UINavigationController *secondNavigationController = [[UINavigationController alloc] initWithRootViewController: svc];
// Initialize tab bar controller, add tabs controllers
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = #[firstNavigationController, secondNavigationController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
// FirstViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = #"One";
self.view.backgroundColor = [UIColor orangeColor];
UITableViewController *vc1 = [[UITableViewController alloc] init];
UITableViewController *vc2 = [[UITableViewController alloc] init];
UITableViewController *vc3 = [[UITableViewController alloc] init];
vc1.view.backgroundColor = [UIColor redColor];
vc2.view.backgroundColor = [UIColor blueColor];
vc3.view.backgroundColor = [UIColor greenColor];
self.viewControllers = #[vc1, vc2, vc3];
self.segmentTitles = #[#"Red", #"Blue", #"Green"];
self.segmentedControl = [[UISegmentedControl alloc] initWithItems: self.segmentTitles];
[self.segmentedControl addTarget: self
action: #selector(segmentClicked:)
forControlEvents: UIControlEventValueChanged];
self.navigationItem.titleView = self.segmentedControl;
self.segmentedControl.selectedSegmentIndex = 0;
// set the first child vc:
UIViewController *vc = self.viewControllers[0];
[self addChildViewController: vc];
vc.view.frame = self.view.bounds;
[self.view addSubview: vc.view];
self.currentVC = vc;
}
- (void)segmentClicked:(id)sender
{
if (sender == self.segmentedControl)
{
NSUInteger index = self.segmentedControl.selectedSegmentIndex;
[self loadViewController: self.viewControllers[index]];
}
}
- (void)loadViewController:(UIViewController *)vc
{
[self addChildViewController: vc];
[self transitionFromViewController: self.currentVC
toViewController: vc
duration: 1.0
options: UIViewAnimationOptionTransitionFlipFromBottom
animations: ^{
[self.currentVC.view removeFromSuperview];
vc.view.frame = self.view.bounds;
[self.view addSubview: vc.view];
} completion: ^(BOOL finished) {
[vc didMoveToParentViewController: self];
[self.currentVC removeFromParentViewController];
self.currentVC = vc;
}
];
}
So obviously my question is, why does this happen, and what can I do to fix it?
Edit: adding screenshots.
EDIT: Based on the answer below I changed the code in the animation block to:
[self.currentVC.view removeFromSuperview];
if ([vc.view isKindOfClass: [UIScrollView class]])
{
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, self.bottomLayoutGuide.length, 0);
[UIView performWithoutAnimation: ^{
vc.view.frame = self.view.bounds;
((UIScrollView *)vc.view).contentInset = edgeInsets;
((UIScrollView *)vc.view).scrollIndicatorInsets = edgeInsets;
}];
}
else
{
vc.view.frame = self.view.bounds;
}
[self.view addSubview: vc.view];
Now it works. I'm going to try this with a custom UIViewController as well.
The issue is that you do not set the correct content inset to each table view. The system attempts to do it for you, but I guess your setup is too complex for it, and it only does it for the first tableview that is loaded in viewDidLoad. In your loadViewController: method, when replacing the currently displayed view, make sure to set both the contentInset and scrollIndicatorInsets to the values of the previous view. I think the system will manage to set the correct insets later, in case you rotate to landscape. Try it. If it doesn't, you will need to do it on your own in viewDidLayoutSubviews.

iOS How can I set transparent in Container viewcontroller

I had embed UIPageViewController in the Root Viewcontroller.
Like below photo .
But I want to set First,second View controller background transparent, and it's still can show view controller text 1 and 2.
So It will show Root background color(black) and the root view controller can swipe though the uipageviewcontroller.
My pageviewcontroller part code below:
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
self.dataSource = self;
pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor clearColor];
UIViewController *p1 = [self.storyboard
instantiateViewControllerWithIdentifier:#"Intro1ID"];
UIViewController *p2 = [self.storyboard
instantiateViewControllerWithIdentifier:#"Intro2ID"];
myViewControllers = #[p1,p2];
[self setViewControllers:#[p1]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
}
Have anyone can teach me how to set the containerview background color transparent and can show 1 , 2 text?
(It is sample code, so that just 1, 2 text)
thank you very much.
This should do the trick:
[[p1 view] setBackgroundColor:[UIColor clearColor]];
[[p2 view] setBackgroundColor:[UIColor clearColor]];
The issue is that the background view of your UIViewController was not transparent.

Resources