iOS navigation bar subview reappear after removing - ios

I am adding a view to the navigation bar
UIView *mySubView = [UIView alloc] initwithFrame:frame];
[self.navigationController.navigationBar addSubview:mySubView];
I want to remove the view before pushing to secondviewController.
[mySubView removeFromSuperView];
When App launch first time it did not remove the view, so view also visible on secondview navigation bar
I searched and tried many approaches, but didn't find any solution.

Assign a tag to you mysubview like
UIView *mySubView = [UIView alloc] initwithFrame:frame];
mySubView.tag =1;
[self.navigationController.navigationBar addSubview:mySubView];
Then add this line when you push to secondViewController.
[[self.navigationController.navigationBar viewWithTag:1] removeFromSuperview];
Hope it helps you.

Add a value to the tag property of the views you want to remove and check for it before removing the the subview, for example, assuming that you add a non-zero value to your subviews:
for (UIView *view in self.navigationController.navigationBar.subviews) {
if (view.tag != 0) {
[view removeFromSuperview];
}
}
Try this it will help !!!!

Do following for the ViewController in which you are having subView for NavigationBar
in .h
#property (nonatomic, retain) UIView *mySubView;
in .m
- (void)viewDidLoad {
//Your Existing Code + following 2 lines
self.mySubView = [[UIView alloc] initWithFrame:yourFrame];
self.mySubView.backgroundColor = [UIColor whiteColor];
}
- (void)viewWillAppear:(BOOL)animated {
//Your Existing Code + following 1 line
[self.navigationController.navigationBar addSubview:self.mySubView];
}
- (void)viewWillDisappear:(BOOL)animated {
//Your Existing Code + following 1 line
[self.mySubView removeFromSuperview];
}
And you are good to go. Tried and tested.

-(void)viewWillDisappear:(BOOL)animated
{
[self.mySubView removeFromSuperview];
//[_mySubView removeFromSuperview];
}

Related

Copying UIButtons frame gives wrong position

I want to create another UIView / UIButton on an UIButton so I'm getting its' frame and use it in declaration of another UIView but It creates like below screenshot (with blue view). By the way, button is created on storyboard.
I'm using Xcode 9.1 and iOS 11.1
- (void)viewDidLoad {
UIView *picker = [[UIView alloc] initWithFrame:_mButton.frame];
picker.backgroundColor=[UIColor blueColor];
[self.view addSubview: picker];
}
Screenshot 1
Screnshot 2
I guess the proper frames are not calculated in viewDidLoad. You can try to make picker a property and adjust its frame in viewDidLayoutSubviews
#property (strong, nonatomic) UIView *picker;
- (void)viewDidLoad {
[super viewDidLoad];
self.picker = [[UIView alloc] initWithFrame:_mButton.frame];
self.picker.backgroundColor=[UIColor blueColor];
[self.view addSubview: self.picker];
}
- (void)viewDidLayoutSubviews {
self.picker.frame = _mButton.frame;
[super viewDidLayoutSubviews];
}
But off course using storyboard and autolayout would probably be the best sollution if you have this possibility.

How can I refer to the view of a subclass from a superclass in Objective-C?

So I have a few different view controllers that I want to have login screens over, which are just a simple text box over a blurred screen. Thus, I thought the best idea would be to make a superclass called Login that all the different view controllers could use. Here's the code for Login.h:
#import <UIKit/UIKit.h>
#interface Login : UIViewController
#property (strong, nonatomic) UIVisualEffectView *blurEffectView;
#property (strong, nonatomic) UITextField *pass;
- (void) enter;
#end
Login.m:
#import "Login.h"
#interface Login () {
NSString *password;
}
#end
#implementation Login
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"In the Login viewDidLoad");
[self presentLogin];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) presentLogin {
NSLog(#"Presenting the login screen");
[self.view setBackgroundColor:[UIColor whiteColor]];
self.pass = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[self.pass setCenter:self.view.center];
[self.view addSubview: self.pass];
[self.pass addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
self.blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
self.blurEffectView.frame = self.view.bounds;
self.blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view insertSubview:self.blurEffectView belowSubview:self.pass];
}
}
- (void) textFieldDidChange: (UITextField *) t {
if ([self.pass.text isEqualToString:[NSString stringWithFormat:#"17"]]) {
[self.blurEffectView removeFromSuperview];
[self.pass removeFromSuperview];
[self enter];
}
NSLog(#"You're changing the text.");
}
- (void) enter {
//to implement in the subclasses individually
}
#end
The subclass (I am just trying to make one so far) is empty except for a definition of "enter" which simply prints out "login successful". The only output I am getting when I run this is:
In the Login viewDidLoad
Presenting the login screen
Nothing shows up on the screen: just white. I assume this is because I am trying to modify the self.view of the subclass, not the superclass, since the subclass is the thing that is actually getting presented. Is there a better way of doing this? Some other design pattern that I am not thinking of? Or is there an easy way to get around this?
Edit: I just realized that the code I was running was slightly different from what I pasted here. I now updated it, but only the blur shows up, not the text field. Also I realized I had the CGRect wrong, it should be something like CGRectMake(0,0,100,20); so I fixed that, and the text field still doesn't show. Is there a reason that might be happening.
Set your height and width and also set your background color to white . for now it is taking transparent text view
self.pass = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[self.pass setCenter:self.view.center];
[self.pass setBackgroundColor:[UIColor whiteColor]]; // default taking clear color for now

How to change views in controller when the first view has some quit animation?

In my viewController, there are two separate "custom views". And the first view has some quit animations, while the second view has some enter animations. The question is how could I change my view in my viewController exactly after the first view's quit animation is done? I have tried the view.hidden property, but it lost both the quit and the enter animations. I also tried to add some animateWithDuration thing and put the switchView method in the completion block, which turned out to fail, too.
Here is the code of my viewController:
#interface PopingViewController ()
#property (nonatomic, retain) HomepageView *homepage;
#property (nonatomic, retain) AboutView *about;
#end
#implementation PopingViewController
- (void)switchView
{
self.homepage = nil;
self.about = [[AboutView alloc] initWithFrame:self.view.frame];
self.about.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.about];
}
- (IBAction)tap:(UITapGestureRecognizer *)sender
{
// the onTouch method basically does some quit animations which take about 1 sec
[self.homepage onTouch:[sender locationInView:self.homepage]];
[self switchView];// it will execute before the animations are finished!
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.homepage = [[HomepageView alloc] initWithFrame:self.view.frame];
self.homepage.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.homepage];
}
Thanks in advance!
If they are just plain UIView subclasses then you could implement the UIView transition with class method transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion on UIView.
So, for your case, you would do it like this,
- (void)switchView
{
self.about = [[AboutView alloc] initWithFrame:self.view.frame];
[self.view insertSubView:about belowSubView:self.homepage];
self.about.backgroundColor = [UIColor whiteColor];
[UIView transitionFromView:self.homepage toView:self.about duration:0.6 options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionShowHideTransitionViews completion:^(BOOL completed){ [self.homePage removeFromSuperView]; }];
}
Otherwise, if you are adding the UIViewController's view to some view then, you would use the UIViewController containment methods. Look at this for further detail http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html#//apple_ref/doc/uid/TP40007457-CH18-SW6

How to remove a programmatically created subview by pressing a button within the subview

I currently have a barbutton:
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(doneDate:)];
It calls the following action:
- (IBAction)doneDate:(id)sender{
[self removeDateView]
}
Which calls the following method:
- (void)removeDateView{
NSLog(#"subviews of view3.view: %#",self.View3.subviews);
[self.View3.subviews. makeObjectsPerformSelector: #selector(removeFromSuperview)];
}
The subview that I'm trying to remove is
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
At the moment it just deletes everything within that View, I can't seem to remove the view called containerView which has the datepicker and toolbar.
As erhnby stated, you could use a tag - which is a great method, but I always try to shy away from looping through a view's subviews whenever I can. Personally, I would make the view you are going to remove an instance variable, and when you want to remove it you can call remove directly on it... Just made a simple example that does this:
.h file:
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController {
UIView *_containerView;
}
#end
.m file:
#import "TestViewController.h"
#interface TestViewController ()
#end
#implementation TestViewController
- (id)init {
self = [super init];
// create the bar button and set it as the right bar button on the navigation bar
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(removeDoneDate)];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// create the container view and add it as a subview
_containerView = [[UIView alloc] initWithFrame:CGRectMake(20, 100, 100, 100)];
_containerView.backgroundColor = [UIColor redColor];
[self.view addSubview:_containerView];
}
- (void)removeDoneDate {
// remove it
[_containerView removeFromSuperview];
}
#end
Results in this to start:
Press button...
(sorry, didn't realize the white on white would be that hard to see)
set tag for that will remove view
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44.0 + 210)];
[containerView setTag:100];
and find it and removeFromSuperView
for (UIView* view in self.View3.subviews) {
if ([view isKindOfClass:[UIView class]] && view.tag == 100) {
[view removeFromSuperview];
}
}

Two UISearchBars showing up in a view controller when only one is instantiated

I have two search bars shhowing up in a view controller. It's strange because I have the same exact code in another vc and it works fine. (the search bar in the background shouldn't be there)
here's a screenshot:
I added the delegates: <UISearchBarDelegate, UISearchDisplayDelegate>
then in the .h:
#property (nonatomic,retain) IBOutlet UISearchBar *searchBar;
in the .m:
#synthesize searchBar;
in the viewDidLoad:
self.searchBar.frame = CGRectMake(204, 11, 107,44);
self.searchBar.delegate = self;
//customize the searchbar
UITextField *searchField = [self.searchBar valueForKey:#"_searchField"];
[searchField setBackground:[UIImage imageNamed:#"search_panel.png"]];
[self.searchBar setTintColor:[UIColor redColor]];
UIImage *searchimg = [UIImage imageNamed:#"searchfield_bg.png"];
for (UIView *subview in self.searchBar.subviews) {
if ([subview isKindOfClass:NSClassFromString(#"UISearchBarBackground")]) {
UIView *bg = [[UIView alloc] initWithFrame:subview.frame];
bg.backgroundColor = [UIColor colorWithPatternImage:searchimg];
[self.searchBar insertSubview:bg aboveSubview:subview];
[subview removeFromSuperview];
break;
}
}
[self.view addSubview:self.searchBar];
and that's it. I have nothing to do with the searchBar in the Storyboard view controller xib it's added programmatically in the viewDidLoad method
thanks for any help
If you're using an outlet, your UISearchBar very likely also exists in the storyboard or the xib. Since you're also creating it in the viewDidLoad, you're making a second copy of it. Take another look at your storyboard.

Resources