I have requirement like inside the view I need to push some other view controllers. For that I tried to add a one window as subview for that particular view then I have given the desired view controller to root view controller for that window. It is showing correctly but the rootviewcontroller is starting from screen (0, 0) point instead of within the window.
In this picture red color is the view controller and gray one is the view with the origin (0, 100). Below is the code I have tried.
UIWindow *insideWindow = [[UIWindow alloc] initWithFrame: CGRectMake(0, 100, _windowView.frame.size.width, _windowView.frame.size.height)];
insideWindow.backgroundColor = [UIColor yellowColor];
insideWindow.windowLevel = UIWindowLevelNormal;
insideWindow.hidden = NO;
insideWindow.clipsToBounds = YES;
insideWindow.bounds = _windowView.bounds;
_windowView.clipsToBounds = YES;
[_windowView addSubview: insideWindow];
SecondViewController *s = [SecondViewController new];
s.view.bounds = CGRectMake(0, 100, _windowView.frame.size.width, _windowView.frame.size.height);
insideWindow.rootViewController = [SecondViewController new];
[insideWindow makeKeyAndVisible];
It is not a duplicate with how to add multiple UIWindows. Here I can able to add the multiple windows But the problem is inside window the viewcontrollers are not setting properly.
I don't really know what you want to achieve but here we go...
SecondViewController *s = [SecondViewController new];
s.view.bounds = CGRectMake(0, 100, _windowView.frame.size.width, _windowView.frame.size.height);
insideWindow.rootViewController = [SecondViewController new];
You basically create an instance of SecondViewController, then you set the bounds (wrong idea) then you assign as window rootViewController another instance of SecondViewController.
The difference between the frame and bounds of a view: Bounds vs Frame
If you want to go that way, then:
SecondViewController *s = [SecondViewController new];
s.view.frame = CGRectMake(0, 100, _windowView.frame.size.width, _windowView.frame.size.height);
insideWindow.rootViewController = s;
Instead of adding windows to display view controllers why you don't add the "SecondViewController" as child to the controller which has the "gray" view?
SecondViewController *s = [SecondViewController new];
[firstViewController addChildViewController:s];
s.view.frame = grayView.bounds; // or CGRectMake(...)
[grayView addSubview:s.view];
[s didMoveToViewController:firstViewController];
Related
I am using following code to add child view controller within another viewcontroller.
CGRect rightViewFrame = CGRectMake(0, 0, self.view.bounds.size.width,self.view.bounds.size.height-50);
[pWorksetController viewDidAppear:YES];
UIStoryboard *pModelViewStoryboard = [UIStoryboard storyboardWithName:#"ModelViewMobile" bundle:nil];
gpUserDataManager.pModelViewController =
(ModelViewController*)[pModelViewStoryboard instantiateViewControllerWithIdentifier:#"VIEW_DETAIL"];
// pModelViewController.selectedModel = pModelListInfo;
gpUserDataManager.pModelViewController.DiscussionViewListingDelegate = self;
//offline model
gpUserDataManager.pModelViewController.syncAllButton = self.syncAllButton;
//offline model
//[self UpdateView];
gpUserDataManager.pModelViewController.modelViewDelegate = self;
gpUserDataManager.pModelViewController.navigationController.navigationItem.hidesBackButton =TRUE;
self.pRightNavController = [[UINavigationController alloc] initWithRootViewController:gpUserDataManager.pModelViewController];
[self.pRightNavController.view setFrame:rightViewFrame];
self.pRightNavController.view.layer.cornerRadius = 5.0;
self.pRightNavController.view.clipsToBounds = YES;
self.pRightNavController.navigationBar.translucent = NO;
[self.view addSubview:self.pRightNavController.view];
[self addChildViewController:self.pRightNavController];
Childviewcontroller's navigation is not starting from proper position.It comes under navigation bar.Please see attached screenshot-1.This only happens while running application on iphone x.It looks properly in other devices.How to resolve this?
Update: When i uncheck under top bars and bottom bars it shifts uiviewcontroller below.Please refer to second screenshot-2.
Just uncheck:
Under Top Bars
Under Bottom Bars
I am trying to change the preferred content size of a UIPopOverController from inside the childViewController.
Firstly I present PopOverViewController this way
DateViewController *dateView = [[DatePickerViewController alloc] initWithNibName:#"DateViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:dateView];
m_tableCell = (NotesCell *)[m_tableView cellForRowAtIndexPath:indexPath];
popViewController = [[UIPopoverController alloc] initWithContentViewController:navController];
popViewController.backgroundColor = [[AppManager instance].themeManager navigationBarColor];
popViewController.delegate = self;
//the rectangle here is the frame of the object that presents the popover,
//in this case, the UIButton…
CGRect popRect = CGRectMake(m_tableCell.customView.frame.origin.x,
m_tableCell.customView.frame.origin.y,
m_tableCell.customView.frame.size.width,
m_tableCell.customView.frame.size.height);
[popViewController presentPopoverFromRect:popRect
inView:m_tableCell
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
So inside my childViewController i.e (DateViewController), I have button which when toggled will call a function
- (void)toggleButton
{
if(small)
{
self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320,485);
}
else
{
self.presentingViewController.presentedViewController.preferredContentSize = CGSizeMake(320,320);
}
}
This is working fine, but as we know that UIPopOverViewController has arrow, so when I resize the popOverView, the arrow also animates up and down, which I dont want. I cannot show this in image, so please excuse me for that.
Need help
Ranjit.
First of all the code you posted won't work, because in else statement you assign CGSizeMake giving only one value while constructing it.
Secondly you can define in which directions you allow for that arrow by specifying popoverArrowDirection property
I have a requirement where I need to slide the view but thats inside a UITabBarController.
Does any one tried doing that ? ECSlidingViewController works perfect if I make it rootViewController but I want that in UITabBarController.
I tried setting the ECSlidingViewController as one of the view controllers for the UITabBarController but it keeps crashing after the first swipe or some times it goes in infinite loop
Below is my code
myWorkController = [[TaskWorkViewController alloc] initWithNibName:#"WorkViewController_iPhone" bundle:nil]; // This is the controller where I have my specific logic
myWorkNavController = [[[UINavigationController alloc] initWithRootViewController:myWorkController] autorelease]; // setting the myWorkController to UINavigationController as I need to navigate from this view controller to different view on specific actions
//SlidingviewController setup
self.slidingViewController = [ECSlidingViewController slidingWithTopViewController:myWorkNavController];
self.slidingViewController.topViewController = myWorkNavController;
[myWorkNavController.view addGestureRecognizer:self.slidingViewController.panGesture];
self.slidingViewController.anchorRightPeekAmount = 100.0;
myWorkController.slidingViewController = self.slidingViewController;
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = #[ self.slidingViewController, createNavController, currentWorkNavController];
and I am setting the underRightViewController inside myWorkController
if (self.slidingViewController != nil)
{
UIViewController *underRightViewController = [[[UIViewController alloc] init] autorelease];
// configure under right view controller
underRightViewController.view.layer.borderWidth = 0;
underRightViewController.view.layer.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0].CGColor;
underRightViewController.view.layer.borderColor = [UIColor colorWithWhite:0.8 alpha:1.0].CGColor;
underRightViewController.edgesForExtendedLayout = UIRectEdgeTop | UIRectEdgeBottom | UIRectEdgeRight; // don't go under the top view
self.slidingViewController.underRightViewController = underRightViewController;
}
1) First swipe works perfect but the second swipe breaks in ECSlidingViewController code
2) As I am using UINavigationController, when I try to change underRightViewController it fails at [oldUnderRightViewController removeFromParentViewController]; of ECSlidingViewController code
Can some one please guide me what I am doing wrong or if this is possible with ECSlidingViewController
Thanks in advance
I am trying to set up a UIScrollView so that I can swipe between my 3 view controllers. This is my code in AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.;
UIScrollView *sv = [[UIScrollView alloc] init];
BarsViewController *bvc = [[BarsViewController alloc] init]; // Create BarsViewController
StopwatchViewController *svc = [[StopwatchViewController alloc] init]; // Create StopwatchViewController
TimerViewController *tvc = [[TimerViewController alloc] init]; // Create TimerViewController
[sv addSubview:bvc.view];
[sv addSubview:svc.view];
[sv addSubview:tvc.view];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade]; // Hide status bar
self.window.rootViewController = sv;
[self.window makeKeyAndVisible];
return YES;
}
It gives an error on this line:
self.window.rootViewController = sv;
saying, "Incompatible pointer types assigning to 'UIViewController *' from UIScrollView *'".
However, there is no such thing as a UIScrollViewController, so I don't know what to do.
Basically, I just want the whole screen to be a scroll view which allows me to swipe between my 3 view controllers. How would I go about doing that?
UPD: June, 2015
Swift
The concept remains the same, which is described below in Objective-C section. There is a little change in syntax. To add childviewcontroller use following snippet:
let aViewController = storyboard.instantiateViewControllerWithIdentifier("A") as! AViewController;
addChildViewController(aViewController);
scrollView!.addSubview(aViewController.view)
aViewController.didMoveToParentViewController(self)
Check my Swift Github Sample Code
Objective-C
Create your own custom container view controller (I will call it combinedViewController), which will hold your three controllers in scroll view.
Inherit like you always do UIViewController, then use addChildViewController public API in your new combinedViewController -viewDidLoad: like this:
[self addChildViewController:aViewController];
[self.scrollView addSubview:aViewController.view];
[aViewController didMoveToParentViewController:self];
Here’s what the code does:
It calls the container’s addChildViewController: method to add the child.
It accesses the child’s view property to retrieve the view and adds it to its own view hierarchy. The container sets the child’s size and position before adding the view; containers always choose where the child’s content appears.
It explicitly calls the child’s didMoveToParentViewController: method to signal that the operation is complete.
Do this operation with each of your viewControllers. Afterwards, set your combinedViewController as a rootViewController.
if you need further explanation, feel free to ask.
Reference: Design custom container view controller
Here you are my Objective-C Github sample code
UPD: Thanks #Oliver Atkinson for clarifying that addChildViewController: method also calls the child’s willMoveToParentViewController: method automatically.
Results:
let obj1 = self.storyboard?.instantiateViewControllerWithIdentifier("DocumentsVC") as! DocumentsVC
let obj2 = self.storyboard?.instantiateViewControllerWithIdentifier("AppointmentsVC") as! AppointmentsVC
let obj3 = self.storyboard?.instantiateViewControllerWithIdentifier("DashboardVC") as! DashboardVC
self.containerScrollView.frame = obj2.view.frame
self.containerScrollView.addSubview(obj2.view)
obj2.willMoveToParentViewController(self)
self.addChildViewController(obj2)
self.containerScrollView.addSubview(obj1.view)
obj1.willMoveToParentViewController(self)
self.addChildViewController(obj1)
self.containerScrollView.addSubview(obj3.view)
obj3.willMoveToParentViewController(self)
self.addChildViewController(obj3)
self.containerScrollView.contentSize = CGSizeMake(3*UIScreen.mainScreen().bounds.width, 0)
obj1.view.frame.origin = CGPointMake(0, 0)
obj2.view.frame.origin = CGPointMake(UIScreen.mainScreen().bounds.width, 0)
obj3.view.frame.origin = CGPointMake(2*UIScreen.mainScreen().bounds.width, 0)
Swift 3.0
Based on Sachin answer - bit more generic - just add next element to views array
var views = [ViewController(), ViewController2(), ViewController3(), ViewController4()]
func setupScrollView() {
scrollView.frame = views.first!.view.frame
scrollView.contentSize = CGSize(width: CGFloat(views.count) * width, height: 0)
_ = views.map({ addViewToScrollView($0) })
_ = views.map({ $0.view.frame.origin = CGPoint(x: CGFloat(views.index(of: $0)!) * width, y: 0) })
}
func addViewToScrollView(_ viewController: UIViewController) {
scrollView.addSubview(viewController.view)
views.willMove(toParentViewController: self)
addChildViewController(viewController)
}
Try this git repo, Using this repo you can create a view navigation like Snapchat/Tinder Main Pages.
https://github.com/goktugyil/EZSwipeController
I have tried to set the animation of a modalviewcontroller to false and the frame adjustments is not working, but when i try to turn the animation on it will work normally. Is there a fix for this?
below is the context of my code:
MyModal *modal = [[MyModal alloc] initWithNibName:#"MyModal" bundle:nil];
modal.modalPresentationStyle = UIModalPresentationFormSheet;
modal.view.superview.frame = CGRectMake(0, 0, 458, 230);
modal.view.superview.center = self.view.center;
[self.navigationController presentModalViewController:modal animated:NO];
What you are trying to do is actually wrong. From your code;
MyModal *modal = [[MyModal alloc] initWithNibName:#"MyModal" bundle:nil];
modal.modalPresentationStyle = UIModalPresentationFormSheet;
modal.view.superview.frame = CGRectMake(0, 0, 458, 230);
modal.view.superview.center = self.view.center;
[self.navigationController presentModalViewController:modal animated:NO]
The above code will never work because you are setting the frame of a view which is not yet created.
So, you can set the frame only after the new view is created or presented.
In your MyModal viewcontroller, set the frame in viewDidAppear (take care not to do it in viewWillAppear)
- (void) viewDidAppear:(BOOL)animated
{
// code to set the frame here
}
Hope this helps.
In my opinion,you should take the code
modal.view.superview.frame = CGRectMake(0, 0, 458, 230);
modal.view.superview.center = self.view.center;
to the MyModal's -(void)viewDidLoad or -(void)viewWillAppear method.
Launch view from nib needs more time than code;Before you launch view to memory,the nil modal.view's frame has already reset,then loads the nib's frame.As you turn off the animation, animation needs time to show,then,the frame could be resize.