I have created a navigation controller with a stack of view controllers.
I want to add a subview at the bottom which stays static (does not move) while the user navigates between this stack of views.
Like in some apps, there is an "ads bar" at the bottom.
How can I do this?
If I understand correctly, this is what you want:
You can to this by creating a custom UIViewController that encloses the UINavigationController. Create a new class called "CustomViewController", and paste the following code:
Interface
#import <UIKit/UIKit.h>
#interface CustomViewController : UIViewController
- (id)initWithViewController:(UIViewController*)viewController bottomView:(UIView*)bottomView;
#end
Implementation:
#import "CustomViewController.h"
#implementation CustomViewController
- (id)initWithViewController:(UIViewController*)viewController bottomView:(UIView*)bottomView
{
self = [super init];
if (self) {
// Set up view size for navigationController; use full bounds minus 60pt at the bottom
CGRect navigationControllerFrame = self.view.bounds;
navigationControllerFrame.size.height -= 60;
viewController.view.frame = navigationControllerFrame;
// Set up view size for bottomView
CGRect bottomViewFrame = CGRectMake(0, self.view.bounds.size.height-60, self.view.bounds.size.width, 60);
bottomView.frame = bottomViewFrame;
// Enable autoresizing for both the navigationController and the bottomView
viewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
bottomView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
// Add views as subviews to the current view
[self.view addSubview:viewController.view];
[self.view addSubview:bottomView];
}
return self;
}
#end
Now to use the CustomViewController:
UIView *myBottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 100)];
myBottomView.backgroundColor = [UIColor redColor];
CustomViewController *customViewController = [[CustomViewController alloc] initWithViewController:<yourNavigationController> bottomView:myView];
Why not to add this static subview at the same level as your Navigation Controller view (usually level near UIWindow). Just add it there and make it top most.
Related
I created a xib file.
Below is the code:
#import "LoginView.h"
#implementation LoginView
-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setup];
}
return self;
}
-(void) setup{
[[NSBundle mainBundle] loadNibNamed:#"LoginView" owner:self options:nil];
self.bounds = self.loginView.bounds;
[self addSubview:self.loginView];
}
Now I created a view controller and add a UIView to it. In viewWillAppear, I am trying to load the xib file into a defined UIView in my view controller.
-(void)viewWillAppear:(BOOL)animated{
self.containerView.layer.borderColor = [UIColor blackColor].CGColor;
self.containerView.layer.borderWidth = 2.0f;
LoginView *loginView = [[LoginView alloc] initWithFrame:CGRectMake(self.containerView.frame.origin.x,self.containerView.frame.origin.y, self.containerView.frame.size.width, self.containerView.frame.size.height)];
[self.containerView addSubview:loginView];
}
But, the xib file is going outside the defined UIView which I named containerView. I have linked the containerView to UIView in ViewController.
#property(nonatomic, weak) IBOutlet UIView *containerView;
Can anyone help me why I am getting this output? I need to get the custom uiview inside the containerView in ViewController. Like the textfields and buttons should be inside the black border.
As you are adding your view on container view then x and y should be 0,0
You need to replace this :
LoginView *loginView = [[LoginView alloc] initWithFrame:CGRectMake(self.containerView.frame.origin.x,self.containerView.frame.origin.y, self.containerView.frame.size.width, self.containerView.frame.size.height)];
by this:
LoginView *loginView = [[LoginView alloc] initWithFrame:CGRectMake(0,0, self.containerView.frame.size.width, self.containerView.frame.size.height)];
Hope this Helps!
I've built an UIView in storyboard that is composed like this:
UIView (called _view)
UIVisualEffetView (dark)
UIVIew
Button
I've done like this for the ability to reuse it between several Navigation Controller. So for this I've set everything and I can show my view in my main controller called "ViewController" that is embedded in a navigation controller. But the issue is that the blur is opaque, for example the blue navigation bar of my view controller is not visible under the UIVIsualAffectView !
Here is the code I use for setting up the custom view :
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
_view.backgroundColor = [UIColor clearColor];
UIView *rootView = [[[NSBundle mainBundle] loadNibNamed:#"SideMenuView" owner:self options:nil] objectAtIndex:0];
CGRect newFrame = rootView.frame;
newFrame.size.width = [[UIScreen mainScreen] bounds].size.width / 2;
newFrame.size.height = [[UIScreen mainScreen] bounds].size.height;
[rootView setFrame:newFrame];
UIWindow* currentWindow = [UIApplication sharedApplication].keyWindow;
currentWindow.backgroundColor = [UIColor clearColor];
currentWindow.windowLevel = UIWindowLevelNormal;
[currentWindow addSubview:rootView];
}
And here is the code I use to call the view from my main controller:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.leftBarButton setTarget:self];
[self.leftBarButton setAction: #selector(test)];
}
- (void)test {
SideMenuView *test = [[SideMenuView alloc] init];
[self.view addSubview:test];
test.translatesAutoresizingMaskIntoConstraints = NO;
}
I've also tried to force the property "setOpaque" to No in my SideMenuView.m but without effect
Here is a screenshot of what it do:
Do you know guys what is wrong with my code ?
I've also added a button in the middle of the screen with a blue background but it's not visible under the blur so the issue is not navigation bar specific
Thanks in advance for your help !
I've resolved my issue by simply creating an UIView with clear background.
What I do for adding the blur effect is to create the UIVisualEffectView programmatically (doing this way it work perfectly !).
After that I'm adding my UIView as a subview of my UIVisualEffectView and voila :)
How to create a simple scroll view when clicking a button in Xcode?
I have assigned the button and gave IBAction as press,
what to code to make a scroll view on this action?
-(IBAction)press
{
}
In .h file you must add delegate definition to your class declaration - something like this:
#interface someClass : NSObject <UIScrollViewDelegate>
In .m write somethink like this:
-(IBAction)press
{
UIScrollView *_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
_scrollView.backgroundColor = [UIColor clearColor];
_scrollView.userInteractionEnabled = YES;
_scrollView.delegate = nil;
[self.view addSubview:self.scrollView];
}
That's all! :)
when I scroll on UIScrollView that not scrolling . Also I am setting scrollview's contentSize.
When I show one other subView and after when I show my view , it's scrolling.
You can see what is problem on this video . How can I solve this problem?
myViewController.h file
#import <UIKit/UIKit.h>
#interface myViewController : UIViewController
#property(nonatomic,retain)UIView * rightTabView;
#property(nonatomic,retain)UIView * leftTabView;
#property(nonatomic,retain)UIView * middleTabView;
#property(nonatomic,retain)UIScrollView *myscrollview;
#end
myViewController.m file
- (void)viewDidLoad
{
// Do any additional setup after loading the view from its nib.
[super viewDidLoad];
//create Tab views and addSubview
CGFloat barHeight=58;
self.rightTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+55,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
[self.view addSubview:self.rightTabView];
self.leftTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+5,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
self.leftTabView.backgroundColor=[UIColor redColor];
[self.view addSubview:self.leftTabView];
self.middleTabView=[[UIView alloc] initWithFrame:CGRectMake(0, barHeight+55,self.view.bounds.size.width,self.view.bounds.size.height-barHeight-55)];
[self.view addSubview:self.middleTabView];
//add Subview to leftTabView
myscrollview=[[UIScrollView alloc]initWithFrame:CGRectMake(10, 10,300, 340)];
myscrollview.userInteractionEnabled=YES;
myscrollview.backgroundColor = [UIColor greenColor];
myscrollview.delegate = self;
[self.leftTabView addSubview:myscrollview];
myscrollview.contentSize = CGSizeMake(2000, 2000);
}
It looks like your middleTabView is obscuring your leftTabView (which is the superview of your scrollview). Either bring the leftTabView to the top of the view hierarchy:
[self.leftTabView.superview bringSubViewToFront:self.leftTabView];
or disable user interactions or visibility of your middleTabView (or add the leftTabView last).
In my app, I have a split screen in which the detail view is a scrollview. I have 5 tables which are subviews of my scrollview in which 3 table views are side by side on top and 2 table views are side by side on bottom
I have already implemented a way in which when I click any of the rows of any of the table in the scrollview, that view disappears and another view zooms into its position.
I write the following code in the didSelectRowAtIndexPath in the middle table subview,
CGFloat xpos = self.view.frame.origin.x;
CGFloat ypos = self.view.frame.origin.y;
self.view.frame = CGRectMake(xpos+100,ypos+150,5,5);
[UIView beginAnimations:#"Zoom" context:NULL];
[UIView setAnimationDuration:2];
self.view.frame = CGRectMake(xpos,ypos,220,310);
[UIView commitAnimations];
[self.view addSubview:popContents.view];
popContents is the view I need to zoom into to the view previously occupied by that particular table view and that happens correctly.
However the problem that I am facing is that since there is another table subview in the side, if I increase the frame size to say 250 or so, the part of the zoomed in view gets hidden by the tableview on the side ( as its as if a part of the zoomed in view goes under the tableview on the side).
Is there anyway to correct this so that my zoomed in view would not get hidden by the tableviews on its sides?
I hope I have explained my problem correctly...
UPDATE:
Here is the code I am using for adding the subviews for the scrollview
// Scroll view
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 30, 1000, 740)];
scrollView.contentSize = CGSizeMake(1000, 700);
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
scrollView.showsHorizontalScrollIndicator = YES;
scrollView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
[self.view addSubview:scrollView];
aView = [[aViewController alloc] initWithNibName:#"aViewController" bundle:nil];
aView.view.frame = CGRectMake(10, 25, 220, 310);
[aView loadList:objPatients];
[scrollView addSubview:aView.view];
bView = [[bViewController alloc] initWithNibName:#"bViewController" bundle:nil];
bView.view.frame = CGRectMake(10, 350, 220, 310);
[bView loadList:objPatients];
[scrollView addSubview:bView.view];
cView = [[cViewController alloc] initWithNibName:#"cViewController" bundle:nil];
cView.view.frame = CGRectMake(240, 25, 220, 310);
[cView loadList:objPatients];
[scrollView addSubview:cView.view];
dView = [[dViewController alloc] initWithNibName:#"dViewController" bundle:nil];
enView.view.frame = CGRectMake(240, 350, 220, 310);
[enView loadList:objPatients];
[scrollView addSubview:dView.view];
eView = [[eViewController alloc] initWithNibName:#"eViewController" bundle:nil];
eView.view.frame = CGRectMake(470, 25, 220, 310);
[eView loadList:objPatients];
[scrollView addSubview:eView.view];
say for example, I add the code for didSelectRowAtIndexPath in cViewController subview...
This is a guess since I would need to know how your table views are added to the scroll view, but the middle table view was probably added before the one on the side. Views are "stacked" in the order they're added with the last one on top. You'll need to get the scroll view to move the middle view to the front with this method
- (void)bringSubviewToFront:(UIView *)view
The best way to do that would be to create a protocol for the table views and make the scroll view the delegate. The method would be something like this
- (void) moveAViewToFront: (MyTableView *) aTableView
{
[self.view bringSubviewToFront: aTableView.view];
}
You would then call the delegate method before setting up the animation.
Edited
After a little more thought I realized that the subviews have a reference to their superview so this bit of code should provide an idea on how to solve the problem. I created a test app which has a view controller which adds two sub views. The view controller header file is MoveSubviewViewController.h
#import <UIKit/UIKit.h>
#interface MoveSubviewViewController : UIViewController
{
}
#end
and it's implementation is
#import "MoveSubviewViewController.h"
#import "MoveableSubview.h"
#implementation MoveSubviewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Create two overlapping subviews. The blue subview will start at the top of
// the frame and extend down two thirds of the frame.
CGRect superviewFrame = self.view.frame;
CGRect view1Frame = CGRectMake( superviewFrame.origin.x, superviewFrame.origin.y,
superviewFrame.size.width, superviewFrame.size.height * 2 / 3);
MoveableSubview *view1 = [[MoveableSubview alloc] initWithFrame: view1Frame];
view1.backgroundColor = [UIColor blueColor];
[self.view addSubview: view1];
[view1 release];
// The green subview will start one third of the way down the frame and
// extend all the to the bottom.
CGRect view2Frame = CGRectMake( superviewFrame.origin.x,
superviewFrame.origin.y + superviewFrame.size.height / 3,
superviewFrame.size.width, superviewFrame.size.height * 2 / 3);
MoveableSubview *view2 = [[MoveableSubview alloc] initWithFrame: view2Frame];
view2.backgroundColor = [UIColor greenColor];
[self.view addSubview: view2];
[view2 release];
}
#end
The subview class is MoveableSubview with another simple header
#import <UIKit/UIKit.h>
#interface MoveableSubview : UIView
{
}
#end
and implementation
#import "MoveableSubview.h"
#implementation MoveableSubview
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Move this view to the front in the superview.
[self.superview bringSubviewToFront: self];
}
#end
The thing to do is to add the
[self.superview bringSubviewToFront: self];
line before setting up the animation.