SteveDolphin23
SteveDolphin23

Reputation: 81

Add a UIProgressView under the Navigation Controller

This seems similar to this question (Showing a UIProgressView inside or on top of a UINavigationController's UINavigationBar) but I cannot get the answer there to work for me without Xcode throwing some hideous error.

I have a similar problem but I'm wanting to add the progress bar on the master view of a split view controller, so it is a tableview but the code given in the above answer doesn't work (I don't have access to the Navigation Bar in the same way.

I've tried reworking it as such:

    UIProgressView *progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];;
[progress setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.navigationController.navigationBar addSubview:progress];

Which very almost works, but it adds it above the view and not below and half-width (annoyingly). I can do this in the storyboard but when I dynamically push a new tableview onto the navigation stack it then dissapears again.

I'm aiming for this:

Progressview Under Nav

Thanks for any help!

Upvotes: 4

Views: 3460

Answers (3)

Alexander Macleod
Alexander Macleod

Reputation: 145

// Add progress view to bar
myProgressView.frame = CGRect(x: 0, y: 64, width: self.view.frame.width, height: 4)
myProgressView.alpha = 0
myProgressView.backgroundColor = Color.dark()
myProgressView.tintColor = UIColor.white

navigationController!.view.addSubview(myProgressView)

Upvotes: 0

J.Williams
J.Williams

Reputation: 1425

override func viewDidLoad() {
    super.viewDidLoad()

    // if VC is pushed in a navigation controller I add a progress bar
    if let navigationVC = self.navigationController {

        // create progress bar with .bar style and add it as subview
        let progressBar = UIProgressView(progressViewStyle: .Bar)
        navigationVC.navigationBar.addSubview(progressBar)

        // create constraints
        // NOTE: bottom constraint has 1 as constant value instead of 0; this way the progress bar will look like the one in Safari
        let bottomConstraint = NSLayoutConstraint(item: navigationVC.navigationBar, attribute: .Bottom, relatedBy: .Equal, toItem: progressBar, attribute: .Bottom, multiplier: 1, constant: 1)
        let leftConstraint = NSLayoutConstraint(item: navigationVC.navigationBar, attribute: .Leading, relatedBy: .Equal, toItem: progressBar, attribute: .Leading, multiplier: 1, constant: 0)
        let rightConstraint = NSLayoutConstraint(item: navigationVC.navigationBar, attribute: .Trailing, relatedBy: .Equal, toItem: progressBar, attribute: .Trailing, multiplier: 1, constant: 0)

        // add constraints
        progressBar.translatesAutoresizingMaskIntoConstraints = false
        navigationVC.view.addConstraints([bottomConstraint, leftConstraint, rightConstraint])
    }
}

Upvotes: 6

David Hoerl
David Hoerl

Reputation: 41642

This technique is working fine for me. In addition to adding it to the nav bar, add constraint that keep it .5 or 1 pixel above the bottom and pin it to the left and right sides. Then it works in landscape too.

In my case I used a nav controller subclass, had it add and hide the progress control, then provide convenience method to allow any view controller to access it.

EDIT: the code but has not been compiled or used by me since 2013. Its in the Navigation Controller subclass:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.

UIProgressView *progress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
progress.tag = DISPLAY_PROGRESS_VIEW;
[self.view addSubview:progress];
UINavigationBar *navBar = [self navigationBar];

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];

[progress setTranslatesAutoresizingMaskIntoConstraints:NO];
progress.hidden = YES;

UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[navBar addGestureRecognizer:longPressGesture];
}

Upvotes: 0

Related Questions