Currently, I am running with the problem while applying the selected image over UITabBarButton. When I am doing this it changes the hierarchy of UITabBarbutton within tabBar.items. Really don't have any idea why this is happening. Posting the code-
UIWindow *keyWindow = [[UIApplication sharedApplication]keyWindow];
UITabBarController *tabBarController =(UITabBarController*)[keyWindow rootViewController];
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *targetTabBarItem = [[tabBar items] objectAtIndex:1]; // whichever tab-item
[targetTabBarItem setSelectedImage:image];
[targetTabBarItem setImage:image];
What I am doing here is-
Getting the image from the server and applying it over the particular UItabBarbutton image. Whenever I set it, it takes the UITabbarButton and inserts at the last position of all the UITabBarButtons.
Whenever image got changed from the server it's hierarchy got changed somewhat like this-
Here we can see that initially, the order of buttons was Tab1, Tab2 and Tab3, while after changing the selected image it got changed into Tab1, Tab3 and Tab2. It is indicating that the selected image index pops out and always inserts to last in TabBarButtons collection. If I change the selected image at index 0 initially the order would be Tab2, Tab3 and Tab1.
So anyone here can give a brief idea which is going wrong in the code?
Sorry for the long post and thanks in advance as well.
Thanks.
The ordering of the tab bar view hierachy as displayed in the view debugger should be totally independent from the backing tabBarController's tabBar property which is holding the tab bar item array.
My guess is the reason you are seeing this adjustment of the ordering the view hierarchy is because changing the image property will either cause it to be redrawn or removed/readded to the view hierarchy so it will then be the last item added there (this should not at all affect the ordering of the tabBarController.tabBar.items)
You'll see the same thing occur if you just change the title of a tab bar item.
I rigged up a button to change the index 1 tab bar item image similar to the code you show, then display the tab bar ordering in a label:
- (IBAction)changeTabBarImage:(id)sender {
UIWindow *keyWindow = [[UIApplication sharedApplication]keyWindow];
UITabBarController *tabBarController =(UITabBarController*)[keyWindow rootViewController];
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *targetTabBarItem = [[tabBar items] objectAtIndex:1]; // whichever tab-item
NSMutableString *tabBarOrder = [[NSMutableString alloc] init];
for (NSUInteger tabBarIndex = 0; tabBarIndex < [tabBar items].count; tabBarIndex++) {
[tabBarOrder appendString:[NSString stringWithFormat:#"index: %lu title: %#\n", tabBarIndex, [[tabBar items] objectAtIndex:tabBarIndex].title]];
}
self.firstLabel.text = [NSString stringWithString:tabBarOrder];
UIImage *image = [UIImage imageNamed:#"sync"];
[targetTabBarItem setSelectedImage:image];
[targetTabBarItem setImage:image];
}
The only image ever changed is the tab bar at index 1 and the ordering of the tabBarController.tabBar.items remains the same, even though the view hierarchy ordering in the view debugger changes (as you show in your screenshots).
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CocoaViewsGuide/WorkingWithAViewHierarchy/WorkingWithAViewHierarchy.html
If you're seeing something different, i'd recommend adding some additional code, as I'm not able to reproduce the issue with just what you've aded.
Related
I'm drawing a view that contains an xib, multiple times (same uiview) and then update the outlets each time it gets drawn displaying an nsmutablearray with different strings on the outlets
Clicking the view opens a viewcontroller that should be displaying the data from the view (+more), this works perfectly fine except it doesn't know which index of the array it's supposed to be displaying.
I'm trying to figure out a way to manage them in a way that I can see which view is being pressed so I can pass that 'id' onto the new vc (something to uniquely identify the view even though it's the same view being drawn)
Here's how the view is being drawn multiple times
- (void) populateUpcoming:(int)events {
[self resetVariables];
upcomingEventsCenterPos = self.view.frame.size.width / 2 - 159;
for (int i = 0; i < events; i++) {
upcomingEventsY2 = 175 * upcomingEvents2;
UIView *firstViewUIView = [[[NSBundle mainBundle] loadNibNamed:#"UpcomingEventFull" owner:self options:nil] firstObject];
[_scrollView addSubview:firstViewUIView];
CGRect frame = firstViewUIView.frame;
frame.origin.y = 9 + upcomingEventsY2;
frame.origin.x = upcomingEventsCenterPos + upcomingEventsX2;
firstViewUIView.frame= frame;
upcomingEvents2++;
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(tapUpcomingEvent:)];
[firstViewUIView addGestureRecognizer:singleFingerTap];
}
[self setupScroll];
}
I think you can use UITableView and custom UITableViewCell for this purpose. On click of "Add More", add one entry to NSMutableArray and just reload tableview.
And no need to manage index separately, you can get it directly by indexPath.row
Also you don't need to manage scroll view size as tableview automatically adjust is content height according to row.
If you are using same kind of view,then go with this approach, as its easy and will save your time.
The search bar is appearing exactly 64 points too low:
All of the other frames are exactly correct.
Edit:
- It's the UISearchController's view that is getting the wrong origin.y. It gets set to 64, when it should be 0.
If I add this method:
- (void)didPresentSearchController:(UISearchController *)searchController
{
[super didPresentSearchController:searchController];
searchController.view.frame = CGRectMake(0, 0, searchController.view.frame.size.width, searchController.view.frame.size.height);
}
Then the views align. However, its janky because it jumps. If I modify the frame in willPresentSearchController it does not work, as the controller must be doing some sort of layout after its presented.
If I use SparkInspector, and edit the frame of the UISearchBarContainerView from origin 64 (what it gets set at, to 0), the problem is resolved.
Here is my relevant configuration:
self.searchResultsController = [[GMSearchTableViewController alloc] init];
self.definesPresentationContext = YES;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.searchResultsController];
self.searchController.dimsBackgroundDuringPresentation = YES;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.searchBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
[self.view addSubview:self.searchController.searchBar];
I'm not using Interface Builder, everything is configured in code.
I'm positive that setting definesPresentationContext is correct.
The VC sits in a regular UINavigationController, which is inside a SplitViewController (but problem exists on iPhone as well).
I feel like I'm missing a simple configuration option in regards to the UINavigationBar
I also have a different controller that uses a custom Container View Controller model, which is more complex, and that one works.
When I set
self.definesPresentationContext = NO;
This happens:
So now the UISearchBar gets positioned correctly, but the presentation context is wrong, causing the UISearchController's table view to occupy the full view.
Well in classic fashion, I've found a solution (https://stackoverflow.com/a/30010473/579217)
This does the trick:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
if (bar == self.searchController.searchBar) {
return UIBarPositionTopAttached;
}
else { // Handle other cases
return UIBarPositionAny;
}
}
If your tableView is custom UItableView and not a UItableViewController you should hide top of the tableview under navigation bar, because search bar automatically attached on header of table view and if your table view starts under navigation bar i cause this problem. Just make the table view full screen from top of navigation bar.
Okay guys, maybe you can help me out with this one. I'm about ready to pull my hair out.
Recently I decided to upgrade my app and make it look better, and with that I wanted to move it into full support for iPad platforms as well. For a while everything worked great. Just press copy MainWindow.xib for iPad, add the views that I used on the iPhone configurations, and everything should be great, but that didn't work too well. Take a look:
Here is the iPhone screenshot:
Here is the iPad screenshot:
Where's the tab bar? I don't understand! I added the initial view when I was first putting it together, but when I linked all of the IBOutlets to the proper pieces, the tab bar no longer shows up.
Screenshot of IB:
Tab Bar properties:
Tint: A bluish color
Image Tint: A goldish color
Mode: Scale to fill
Tag: 0
User Interaction Enabled: (Checked)
Multiple Touch: (Unchecked)
Alpha: 1
Opaque: (Checked)
Hidden (Unchecked)
Clears Graphic Context: (Checked)
Clip Subviews: (Unchecked)
Autoresize Subviews: (Checked)
Stretching: (x,y,w,h):(0,0,1,1)
The viewController.h file is a delegate for UITabBar, UITextField, and UITextView
ViewDidLoad (bar is the IBOutlet for the tab bar):
- (void)viewDidLoad
{
[super viewDidLoad];
[self playMovieIntro];
NSURL *url = [NSURL URLWithString:#"http://www.faithlifefellowship.us/Audio/Sermons/NewSermonBanner.png"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
if(!image == NULL)
{
NewSermonBanner.image = image;
}
series = [[Series alloc] init];
SeriesName = #"";
NSRange range = [[[UIDevice currentDevice] name] rangeOfString:#"iPad"];
int i = 0;
if(range.location != NSNotFound)
i = 1;
bar.selectedItem = hometab;
//set delegates
[bar setDelegate:self];
[personalName setDelegate:self];
[personalEmail setDelegate:self];
[content setDelegate:self];
[prContent setDelegate:self];
[prName setDelegate:self];
[prEmail setDelegate:self];
}
I'm stumped. If you have any ideas or need any more information, let me know.
Thanks!
I'm going to give you a few things I'm getting in order to fix this. It will be tons easier if you could upload the source code for me/us to download and be able to pinpoint the problem.
Sometimes (I can't remember exactly when) I've had my navigation bar not show up because it was missing a connection.
Make sure you are not hiding the tab bar anywhere in code, though it doesn't seem to be the case since it shows up on iPhone.
Otherwise I'm gonna take a guess and say it's something in the NIB. Here are some things you can try:
Check all your connections to outlets
Make sure your objects in the NIB are of the correct class
Verify that the tab bar's "hidden" property is not check in Interface Builder
Compare and verify all the structure of the NIB file between iPhone and iPad
These are just some ideas :) again if you can post the code it would be fantastic.
Let us know how it goes,
Felipe
I had this problem with a app that support both iPhone and iPad. Make sure 'is initial view controller' is checked for the UITabBarController when you examine the view controller using the object inspector. When you do this, xcode will display a 'inbound' arrow on the left side of the view controller if you're using storyboards.
I have a TabBar that I've created through IB, I chose "create new project" -> "Tab bar application". Is there a way for me to access one of the TabBarItems for customization through the code?
It seems to me that something like:
[[self.tabBarController.tabBar.items objectAtIndex:0] setTitle:#"Button one"];
should set the title of that item to "Button one", but it doesen't. The title itself is not a problem (I can set that through IB aswell), however adding an Icon seems to be.
So to sum up, what I really want to know is: Is there a way to add an Icon to a TabBarItem created through IB?
SOLUTION:
Adding in viewDidLoad in the first view, being loaded automatically upon starting the app:
UITabBarController *tb = [self tabBarController];
[[tb.tabBar.items objectAtIndex:1] setTitle:#"Title"];
Let me set the title of the second button (objectAtIndex: 1). I was also able to set the image the same way, which also worked for buttons one (objectAtIndex: 0) and three (objectAtIndex: 2).
Add this to your viewDidLoad: method of one of the tabBar viewControllers and it should work:
- (void)viewDidLoad
{
[super viewDidLoad];
//Get the tabBarItem
UITabBarItem *tbi = [self tabBarItem];
//Give it a lable
[tbi setTitle:#"Title A"];
//create a image from a file for the tabBar
UIImage *i = [UIImage imageNamed:#"NiceImage.png"];
//and put it on the tabBar
[tbi setImage:i];
}
You should be able to set the image and title properties on the TabBarItems:
UITabBarItem *item = (UITabBarItem *)[tabBarController.tabBar.items objectAtIndex:0];
item.image = [UIImage imageNamed:#"home.png"];
Don't forget that the UITabBar only uses the alpha values out of the image you set, so if you don't have an alpha channel in the image you may not see anything when you set an image on the tab bar item.
I've never created a tab bar through IB (always through code), however to set title and icon I use
controller.title = #"Controller";
controller.tabBarItem.image = [UIImage imageNamed:#"image.png"];
where controller is the UIViewController added to the viewControllers' array of the UITabBarController.
I have a UITableViewController and intend to add a subview to it when I click a button i.e. refresh button. My code is as follows:
//set up loading page
self.myLoadingPage = [[LoadingPageViewController alloc]init ];
self.myLoadingPage.view.frame = self.view.bounds;
self.myLoadingPage.view.hidden = NO;
[self.view addSubview:self.myLoadingPage.view];
My question is how can I set this subview to be in the current visible frame? especially for a UITableviewcontroller where I might click on the refresh button after scrolling down to the 100th cell, for this example, my subview will still be added right at the top of the table view (starting from cell 1). Is there any way to resolve this?
Just move the lines around so that you set the frame after you made it a subview
self.myLoadingPage = [[LoadingPageViewController alloc]init ];
self.myLoadingPage.view.hidden = NO;
[self.view addSubview:self.myLoadingPage.view];
self.myLoadingPage.view.frame = self.view.bounds;