开发者

How to hide master view in UiSplitviewcontroller in ipad

开发者 https://www.devze.com 2022-12-27 18:59 出处:网络
Is there is any way to hide the master view in a splitviewcontroller programmatically. In my applica开发者_如何学Ction the first screen will be of a splitviewcontroller, i don\'t need any split view f

Is there is any way to hide the master view in a splitviewcontroller programmatically. In my applica开发者_如何学Ction the first screen will be of a splitviewcontroller, i don't need any split view for the next screens. How i can achieve this


in SDK 5.0 they added new method for UISplitViewControllerDelegate that would do this easily for you. Just implement it like next and you would not see the master view:

- (BOOL)splitViewController:(UISplitViewController*)svc 
   shouldHideViewController:(UIViewController *)vc 
              inOrientation:(UIInterfaceOrientation)orientation 
{
    return YES;
}

The only place when you can see it is rotation - the part of master view is visible during animation. I've fixed that in simple way, just loaded empty and black view in master.

PS: not sure whether this is actual for i0707. But hope this could be useful for other people that now have the same issues.


Same as answer from Jack but a one liner. Past into - (void)setDetailItem:(id)newDetailItem { ... } to dismiss the master.

[[UIApplication sharedApplication] sendAction: self.navigationItem.leftBarButtonItem.action
                                           to: self.navigationItem.leftBarButtonItem.target
                                         from: nil
                                     forEvent: nil];


Matt Gemmell created an excellent custom splitViewController called "MGSplitViewController". It is very easily implemented, heavily commented, and contains a lot of excellent features not found with a normal splitViewController (hide master view on landscape view, change placement of the split in landscape view, allow user to change size of split fluidly during runtime, etc).

Info and demo: http://mattgemmell.com/2010/08/03/mgsplitviewcontroller-updated/

Straight to the source: https://github.com/mattgemmell/MGSplitViewController/


The BarButtonItem provided by the SplitViewController is the key to programmatically hiding the Master View Controller.

This code is DANGEROUS! but elegant :)

import the objective c message library

#import <objc/message.h>

Next, get a handle to the UIBarButtonItem provided by the SplitViewController

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem
           forPopoverController:(UIPopoverController *)popoverController
    {
        barButtonItem.title = @"Master";
        [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];

        //Obtain handle to BarButtonItem
        [self setMasterButtonItem:barButtonItem];
    }

Then when the event is fired which should trigger the auto-dismissal of the master view controller i.e.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

You can do this

objc_msgSend(self.masterButtonItem.target, self.masterButtonItem.action);


Try this:

splitVC.modalPresentationStyle = UIModalPresentationFullScreen;
[splitVC presentModalViewController:[[splitVC viewControllers] objectAtIndex:1] animated:NO];

Works on 4.2 for me!

Here is another awesome trick that works. video link is here.


The code above didnt work for me, however, when I tried

CGRect selfFrame = self.splitViewController.view.frame; 

it did. So....this works for me.. (this code should be in your detailviewcontroller)

-(void)hideMaster {
    UIViewController *masterController = GetAppDelegate().masterController;

    CGRect selfFrame = self.splitViewController.view.frame; 
    CGFloat aWidth = masterController.view.frame.size.width;

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.30f];

    if(orientation == UIDeviceOrientationLandscapeLeft)
    {
        selfFrame.size.height += aWidth;
        selfFrame.origin.y -= aWidth;
    }
    else if(orientation == UIDeviceOrientationLandscapeRight)
    {
        selfFrame.size.height += aWidth;
    }

    [self.splitViewController.view setFrame:selfFrame];

    [UIView commitAnimations];

    }

To allow rotation this was needed:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration]; // not sure if needed
    //By the time this method is called the bounds of the view have been changed
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];

    if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) {
        if (masterIsHidden) {
            [self showMaster];
        }
    } else {
        if (self.editing) {
            [self hideMaster];
        }
    }
       [UIView setAnimationDuration:duration];
    [UIView commitAnimations];
}


While it will not have nice transitions (sorry), you could do this by setting the root view to the detail view controller's view, and then swap views with the UISplitView and move the detail view to the UISplitView. (Actually you might be able to animate the view swap (push/flip/etc.) but it is a bad idea to change anything during view change animations, and moving the detail view to inside the UISplitView might qualify.)


This works:

Attach the "hide" method to your button, for example:

UIBarButtonItem *hideButton = [[UIBarButtonItem alloc] initWithTitle:@"hide"
                                         style: UIBarButtonItemStylePlain
                                        target: self
                                        action: @selector(hide:)
                              ];

[self.mainView.navigationItem setLeftBarButtonItem:hideButton];

In this code, the "self.mainView" is the view controller in the navigation controller in the second view of the splitview - just as a reference.

The hide method looks like so.

-(void)hide:(id)sender
{
    UIViewController *masterController = [self.viewControllers objectAtIndex:0];

    CGRect selfFrame = self.view.frame; 
    CGFloat aWidth = masterController.view.frame.size.width;

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.30f];

    if(orientation == UIDeviceOrientationLandscapeLeft)
    {
        selfFrame.size.height += aWidth;
        selfFrame.origin.y -= aWidth;
    }
    else if(orientation == UIDeviceOrientationLandscapeRight)
    {
        selfFrame.size.height += aWidth;
    }

    [self.view setFrame:selfFrame];

    [UIView commitAnimations];

}

This is the starting point, obviously more logic needs to be done to take care of rotation, showing it again, etc...

I hope this helps.

Tested with iOS5 and Xcode 4.3


Don't know if this is what your are looking for. For example, to hide master view in landscape mode when a button is clicked you can do the following (in the selector method)

UIViewController *master = [splitViewController.viewControllers objectAtIndex:0];
UIViewController *detail = [splitViewController.viewControllers objectAtIndex:1];

[master.view setFrame:CGRectMake(0, 0, 0, 0)];
detail.view.frame = splitViewController.view.bounds;   // or use master and detail length
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号