I want to have an UIProgressView to show a progress on the bottom of a navigation bar (just like when sending an iMessage or text message in iOS 7). But I need this consistently on every table view view of my navigation controller. So for me it was clear: I have to add this to the UINavigationController. But the problem is, it's not possible to add an UIProgressView to the UINavigationController. So I tried out two things:
1st I tried to add it to UINavigationController's view programmatically. But the problem was to position the UIProgressView and to make it look good when changing device rotation.
The 2nd thing I tried is to add the UIProgressView to every UITableView, but then I really have to do this for every view. Also it doesn't look good, because it is not on top of the navigation bar but beneath it. But the main reason why I didn't like the 2nd solution is because the ProgressViews go and come with their TableView, so you don't have a static one but changing ones.
After this, I don't have any idea to do this, so I ask you… does anyone have an idea how to do this?
That's how it should look like:
Change the Bar Style A user changes the navigation bar's style, or UIBarStyle , by tapping the “Style” button to the left of the main page. This button opens an action sheet where users can change the background's appearance to default, black-opaque, or black- translucent.
According to Apple documentation, "An iOS Navigation bar appears at the top of an app screen, below the status bar, and enables navigation through a series of hierarchical app screens.
Start with Navigation ControllerCreate a single view application in Xcode. Add two view controller into your storyboard. Create two different swift files for those view controllers and set identifiers for them. Take a button in each view controller, set constrain for them and customize as you want.
I finally found a solution:
I made a custom UINavigationController and added this to viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
progress = [[UIProgressView alloc] init];
[[self view] addSubview:progress];
UIView *navBar = [self navigationBar];
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[navBar]-[progress(2@20)]"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(progress, navBar)]];
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[progress]|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(progress)]];
[progress setTranslatesAutoresizingMaskIntoConstraints:NO];
[progress setProgress:0 animated:NO];
}
I created a new UIProgressView (I declared in @interface
) added the constraints to position it beneath the navigation bar and (this step is important:) set translatesAutoresizingMaskIntoConstraints
to NO
.
I reworked the original poster's answer so that the bar is actually just inside the navigation bar. What's nice about this is that when its showing, it overlaps the one pixel bottom line (in effect replacing it), so when you animate the progress bar to hidden, the progress bar fades out and the separator line fades in. The key part of this solution is adding the progress bar to the Navigation Controller's view, not the Navigation bar.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIProgressView *progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];;
[self.view addSubview:progress];
UINavigationBar *navBar = [self navigationBar];
#if 1
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[navBar]-0-[progress]"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(progress, navBar)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[progress]|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(progress)]];
#else
NSLayoutConstraint *constraint;
constraint = [NSLayoutConstraint constraintWithItem:progress attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:navBar attribute:NSLayoutAttributeBottom multiplier:1 constant:-0.5];
[self.view addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:progress attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:navBar attribute:NSLayoutAttributeLeft multiplier:1 constant:0];
[self.view addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:progress attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:navBar attribute:NSLayoutAttributeRight multiplier:1 constant:0];
[self.view addConstraint:constraint];
#endif
[progress setTranslatesAutoresizingMaskIntoConstraints:NO];
[progress setProgress:0.5 animated:NO];
}
I'm not sure why its necessary to add the 0.5 offset to the NSLayoutContstraints code to get the same match, but it is. I use these not the visual formats, but the choice is yours. Note that contraining to the bottoms makes this seamless in rotation too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With