I've set my navbar to white or atleast tried to. However, it hasn't come out looking very white it seems.
Here's the bit of code where I set it.
- (void)viewDidLoad {
[super viewDidLoad];
[self addSidebarNavButton];
// Set the navbar
[self setEdgesForExtendedLayout:UIRectEdgeNone];
UILabel *nav_titlelbl=[[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.navigationItem.titleView.frame.size.width,40)];
nav_titlelbl.text=#"";
nav_titlelbl.textAlignment=NSTextAlignmentCenter;
UIFont *lblfont=[UIFont fontWithName:#"Futura-Medium" size:20];
[nav_titlelbl setFont:lblfont];
self.navigationItem.titleView=nav_titlelbl;
// Set the navbar colour
self.navigationController.navigationBar.barTintColor =
[UIColor colorWithRed:255.0/255.0f green:255.0/255.0f blue:255.0/255.0f alpha:1.0];
self.navigationController.navigationBar.translucent = YES;
Unfortunately I can't attach the navbar image here as I don't have the 10 reputation points needed. However if I could, you'd see that the navbar in question comes out looking light gray!
Set self.navigationController.navigationBar.translucent = NO; you might be seeing the view background.
Related
I have a UIView in which i want to remove the whole background so it would take the shape of a paper. I tried setting the background to transparent from the UI and using the code but i always end up with a gray-like semi transparent background no matter what i do. Here is the current output i am getting :
How can i remove that grey background? i need it to display as a whole paper without that residue. Any Help? I tried the following :
// self.view.backgroundColor = [UIColor clearColor];
//
// [self.view setOpaque:YES];
//
// self.view.backgroundColor = [UIColor clearColor];.
// self.view.layer.borderWidth = 0.0;
// self.view.layer.masksToBounds = YES;
// self.view.backgroundColor=[[UIColor clearColor] colorWithAlphaComponent:.0];
And the current UI Configuration is :
How can i manage to remove it !? Any help!?
EDIT 1
This is the new output
Looks like your image it's inside a Modal View. If that is the case try the following:
Set the self.view.superview.backgroundColor to [UIColor clearColor]; inside the viewWillLayoutSubviews
Example
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.view.superview.layer.masksToBounds = YES;
self.view.superview.backgroundColor = [UIColor clearColor];
}
I'm adding a search bar to the titleView of the navigationItem, so that it looks like this.
But when I tap on the search bar to get focus, it moves out of the screen and the keyboard is dismissed automatically, and then it looks like this.
So, I'm neither able to type anything, nor see any results.
Here is my code where I am adding the search bar to the navigation item in viewDidLoad method.
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0.0, 320.0, 44.0)];
self.searchBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
UIView *searchBarView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 310.0, 44.0)];
[self.searchBar setShowsCancelButton:NO animated:NO];
searchBarView.autoresizingMask = 0;
self.headSearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.headSearchDisplayController.delegate = self;
self.headSearchDisplayController.searchResultsDelegate = self;
self.headSearchDisplayController.searchResultsDataSource = self;
[searchBarView addSubview:self.searchBar];
self.searchBar.delegate = self;
self.navigationItem.titleView =searchBarView;
I tried it without setting the autoresizingmask, without any success. I am getting a hint that this behavior is happening because the search bar is in a view which is 44points, which is again inside the titleView. I am guessing that the searchResultsTableView doesn't have enough height to be seen, and thus we're only able to see the overlay. How do I solve this issue? Pointers in the right direction will be extremely helpful.
Here is an animated gif of the situation.
I figured out that the Navigation bar was usually pushed up, when the search was focused, and since the search bar was in the navigation bar it was pushed up with it, and couldn't be visible on the screen.
I solved this by subclassing the UISearchDisplayController to hide the navigationBar. Here is the code.
#import "CustomSearchDisplayController.h"
#implementation CustomSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
#end
Found this answer here: https://stackoverflow.com/a/3257456/1011042
I’m adding a UISegmentedControl right under the NavigationBar in a UITableViewController. This is the code.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationBar = self.navigationController.navigationBar;
UIView *segmentView=[[UIView alloc] initWithFrame:CGRectMake(0, self.navigationBar.frame.size.height, self.navigationBar.frame.size.width, 50)];
[segmentView setBackgroundColor:[UIColor whiteColor]];
segmentView.alpha = 0.95;
self.tabSegmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Favourites", #"All", nil]];
self.tabSegmentedControl.frame = CGRectMake(20, 10, self.navigationBar.frame.size.width - 40, 30);
[self.tabSegmentedControl addTarget:self action:#selector(tabChanged:) forControlEvents:UIControlEventValueChanged];
[segmentView addSubview:self.tabSegmentedControl];
[self.navigationBar addSubview:segmentView];
[self.tabSegmentedControl setSelectedSegmentIndex:1];
}
The view and the SegmentedControl appear on the screen well, but they are not clickable. The selector doesn’t get executed when tapped on the SegmentControl; it doesn’t even switch tabs! In fact, the stuff that is underneath the segmentView (items in the TableView) get clicked when you tap on it. I have tried but failed to understand why this is happening! Any suggestions would be helpful!
You are adding a view below the bounds of its super view. You may see the view however you cannot click it because it is out of bounds. If you set the property of the navigation bar clipsToBounds to YES you should see that the view disappears. What you need to do is add the segment controller to the table view. Here is an example:
- (void)viewDidLoad
{
[super viewDidLoad];
...
[self.view addSubview: self.segmentView]; // need to keep a pointer to segmentView
self.tableView.contentInset = UIEdgeInset(self.segmentView.frame.size.height, 0,0,0);
}
-(void) scrollViewDidScroll:(UIScrollView*) scrollView{
CGRect rect = self.segmentView.frame;
rect.origin = self.tableView.contentOffset;
self.segmentView.frame = rect;
}
Now it's white dots with black background. What about if I want it to be black dots with white backgrounds?
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0)
{
return _imageArrays.count;
}// The number of items reflected in the page indicator.
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController NS_AVAILABLE_IOS(6_0)
{
return self.intCurrentIndex;
}// The selected item reflected in the page indicator.
You can use UIAppearance to change the color of UIPageControl. Try this in your AppDelegate's didFinishLaunchingWithOptions function.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor blueColor];
return YES;
}
EDIT:
To apply style only to a particular view controller, use appearanceWhenContainedIn instead, as following:
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
Now, only UIPageControl objects contained in the MyViewController are going to adapt this style.
Thanks Mike & Shingoo!
EDIT:
If you see black background around UIPageControl at the bottom of your screen, it is due to the background color of your UIPageViewController not UIPageControl. You can change this color as following:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor]; //Set it to whatever you like
}
I don't believe that you can manipulate the UIPageViewController's page control. My solution:
I have a "root" UIViewController that is UIPageViewControllerDelegate and UIPageViewControllerDataSource.
On this root view controller, I have #property (strong, nonatomic) IBOutlet UIPageControl *pageControl. In the corresponding storyboard nib, I add a UIPageControl, position it, and check "Hides for Single Page". I can also change the colors, if I wish.
Then, I add the following in the root view controller's viewDidLoad: self.pageControl.numberOfPages = [self.features count]
My root view controller also has #property (strong, nonatomic) UIPageViewController *pageViewController. And in the implementation:
self.pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pageViewController.delegate = self;
DataViewController *startingViewController = [self viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
self.pageViewController.view.frame = CGRectMake(0.0, 0.0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height + 10.0);
[self.pageViewController didMoveToParentViewController:self];
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
(SIDE NOTE: That line that sets the frame makes the height of the UIPageViewController's view exceed the screen size so that the native page control is no longer visible. My app is portrait only, iPhone only, so I got off a bit easy here. If you need to handle rotations, you'll have to find a way to keep that native page control offscreen. I tried using auto layout, but UIPageViewController creates a set of magic views that have a bunch of autolayout mask constraints that I couldn't find a way to override.)
Anyway...then I add an extra UIPageViewController delegate method to change my new, non-native UIPageControl to the currently-selected page:
- (void)pageViewController:(UIPageViewController *)viewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
if (!completed){return;}
// Find index of current page
DataViewController *currentViewController = (DataViewController *)[self.pageViewController.viewControllers lastObject];
NSUInteger indexOfCurrentPage = [self indexOfViewController:currentViewController];
self.pageControl.currentPage = indexOfCurrentPage;
}
Not as pretty as I would like, but Apple's API for this class doesn't exactly lend itself to elegance.
You can actually grab it and store it locally in your own property in one of the delegate calls.
Put this code inside your delegate to access the UIPageControl inside the UIPageViewController:
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
[self setupPageControlAppearance];
return kPageCount;
}
- (void)setupPageControlAppearance
{
UIPageControl * pageControl = [[self.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(class = %#)", [UIPageControl class]]] lastObject];
pageControl.pageIndicatorTintColor = [UIColor grayColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
}
You can recursively search it in your subviews
- (void)findAndConfigurePageControlInView:(UIView *)view
{
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UIPageControl class]]) {
UIPageControl * pageControl = (UIPageControl *)subview;
//customize here
pageControl.hidesForSinglePage = YES;
break;
} else {
[self findAndConfigurePageControlInView:subview];
}
}
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
[self findAndConfigurePageControlInView:self.view];
return self.promotionsVCs.count;
}
it works for me
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor redColor];
pageControl.backgroundColor = [UIColor blackColor];
This will change the appearance just for "MyViewController". If you want to have different colors in different page indicators on the same view you have to create different subviews and customize them individually.
Here's what I did in Swift 4. I tried similar answers first, in viewDidLoad, but this is what eventually worked. This same snippet was used to answer similar SO questions.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews{
if view is UIPageControl{
(view as! UIPageControl).currentPageIndicatorTintColor = .yellow
}
}
}
Once you have the UIPageControl in this block, you should be able to customize its indicator colours
If you use the "auto generated" page indicator created by UIPageViewController, I think that you can't customize it. The only way you could do that is to add an extra PageControl, either the one provided by Apple or a custom one as #Maschel proposed.
It is possible to customise it through appearance. You can do it in AppDelegate like this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIPageControl *pageControl = [UIPageControl appearance];
pageControl.pageIndicatorTintColor = [UIColor whiteColor];
pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
pageControl.backgroundColor = [UIColor lightGrayColor];
return YES;
}
If you want to do it just for a certain view controller, replace the pageControl with this instead.
UIPageControl *pageControl = [UIPageControl appearanceWhenContainedIn:[MyViewController class], nil];
This one working perfectly for custom image
self.pageControl.pageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"page_indicater"]];
self.pageControl.currentPageIndicatorTintColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"page_indicater_selection"]];
You can use SMPageControl: Github. It works just like the UIPageControl but with more customisation possibilities.
You can easily access the UIPageViewController's pageControl by defining a computed property like this:
var pageControl: UIPageControl? {
for subview in view.subviews {
if let pageControl = subview as? UIPageControl {
return pageControl
}
}
return nil
}
And then customize it to suite your needs like this:
override func viewDidLoad() {
super.viewDidLoad()
pageControl?.backgroundColor = .white
pageControl?.pageIndicatorTintColor = .red
pageControl?.currentPageIndicatorTintColor = .blue
}
Obvious caveat: if Apple ever decides to change the UIPageViewController view hierarchy this will stop working.
I was just testing my app with iOS 6.0 and Xcode 4.5GM and I have set up a view like this:
[self.view setBackgroundColor:[UIColor groupTableViewBackgroundColor]];
So, the view has the same pattern than a common table view.
This works fine on iOS 4 and 5, but in iOS 6 it just gives me a white background.
Is this deprecated? If so, how can I replace it?
Thanks
This method will be deprecated during the 6.0 seed program
If you want to have a background in your own view that looks like the table view background,
then you should create an empty table view and place it behind your content.
First, add this to your viewDidLoad:
self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"tableViewBackground.png"]];
OR
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"tableViewBackground.png"]];
Then add this images to your app:
tableViewBackground.png
tableViewBackground#2x.png
I've written a UIColor category to replace groupTableViewBackgroundColor:
#interface UIColor (UITableViewBackground)
+ (UIColor *)groupTableViewBackgroundColor;
#end
#implementation UIColor (UITableViewBackground)
+ (UIColor *)groupTableViewBackgroundColor
{
__strong static UIImage* tableViewBackgroundImage = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(7.f, 1.f), NO, 0.0);
CGContextRef c = UIGraphicsGetCurrentContext();
[[self colorWithRed:185/255.f green:192/255.f blue:202/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(0, 0, 4, 1));
[[self colorWithRed:185/255.f green:193/255.f blue:200/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(4, 0, 1, 1));
[[self colorWithRed:192/255.f green:200/255.f blue:207/255.f alpha:1.f] setFill];
CGContextFillRect(c, CGRectMake(5, 0, 2, 1));
tableViewBackgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
});
return [self colorWithPatternImage:tableViewBackgroundImage];
}
#end
This solution also allows to tweak the appearance of the background. Feel free to change the drawing code :)
In iOS6 SKD, comments in UIInterface.h suggest the following:
Group style table view backgrounds can no longer be represented by
a simple color.
If you want to have a background in your own view
that looks like the table view background, then you should create
an empty table view and place it behind your content.
This method will be deprecated during the 6.0 seed program
A simple solution is to set the background with equivalent RGB values:
[self.view setBackgroundColor:[UIColor colorWithRed:215.0/255.0 green:217.0/255.0 blue:223.0/255.0 alpha:1.0]];
You can them set the view background to color to White or whatever you like in the xib to suppress the warning.
If it helps anyone, here's specifically what I'm doing in my custom view to get this background (using hint from Mr Beloeuvre)
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
[self.view addSubview:tv];
[self.view sendSubviewToBack:tv];
// ...
}
Try this:
[myTableView setBackgroundView:nil];
[myTableView setBackgroundView:[[[UIView alloc] init] autorelease]];
You may have difficult time to locate the view if you use storyboard and have many views. You can click on "Show the Version editor" button the right top corner. This will change story view to XML text view. Search for "groupTableViewBackGroundColor". You should find views with this attribute.
It's good idea to use standard methods for previous iOs versions. So I improved solution of James Boutcher:
+ (void)setBackgroundColorForTableView:(UITableView*) tableView
{
UIColor* color = [UIColor whiteColor];
NSString* version = [[UIDevice currentDevice] systemVersion];
if([version floatValue] < 6.0)
{
tableView.backgroundColor = color;
}
else
{
tableView.backgroundView = nil;
UIView* bv = [[UIView alloc] init];
bv.backgroundColor = color;
tableView.backgroundView = bv;
[bv release];
}
}
Elaborating on #NSElvis's solution, here is the identical grouped table view background asset (it's wide enough so you don't get funny effects in landscape orientation)
back-tableview#2x.png
To use it, simply do
[YOUR_VIEW setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"back-tableview"]]];