Le guide de programmation pour iPad indique que le volet gauche du splitView est fixé à 320 points. Mais 320 pixels pour mon contrôleur de vue maître, c'est trop. Je voudrais le réduire et donner plus d'espace au contrôleur de vue de détail. Est-ce possible de toute façon?
Lien vers le document qui parle de largeur fixe.
Si vous sous-classez UISplitViewController, vous pouvez implémenter -viewDidLayoutSubviews
et y ajuster la largeur. C'est propre, pas de piratage ou API privée, et fonctionne même avec la rotation.
- (void)viewDidLayoutSubviews
{
const CGFloat kMasterViewWidth = 240.0;
UIViewController *masterViewController = [self.viewControllers objectAtIndex:0];
UIViewController *detailViewController = [self.viewControllers objectAtIndex:1];
if (detailViewController.view.frame.Origin.x > 0.0) {
// Adjust the width of the master view
CGRect masterViewFrame = masterViewController.view.frame;
CGFloat deltaX = masterViewFrame.size.width - kMasterViewWidth;
masterViewFrame.size.width -= deltaX;
masterViewController.view.frame = masterViewFrame;
// Adjust the width of the detail view
CGRect detailViewFrame = detailViewController.view.frame;
detailViewFrame.Origin.x -= deltaX;
detailViewFrame.size.width += deltaX;
detailViewController.view.frame = detailViewFrame;
[masterViewController.view setNeedsLayout];
[detailViewController.view setNeedsLayout];
}
}
Dans IOS 8.0, vous pouvez facilement le faire en procédant comme suit:
1. Dans votre MasterSplitViewController.h, ajoutez
@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0);
2. Dans votre méthode MasterSplitViewController.m viewDidLoad, ajoutez
self.maximumPrimaryColumnWidth = 100;
self.splitViewController.maximumPrimaryColumnWidth = self.maximumPrimaryColumnWidth;
C’est une très bonne fonctionnalité simple et facile de IOS 8.
ce code est un travail pour moi
[splitViewController setValue:[NSNumber numberWithFloat:200.0] forKey:@"_masterColumnWidth"];
Non.
Il y a deux privés propriétés
@property(access,nonatomic) CGFloat masterColumnWidth;
@property(access,nonatomic) CGFloat leftColumnWidth; // both are the same!
mais étant privé, cela signifie qu'ils ne peuvent pas être utilisés pour les applications AppStore.
iOS 8 a introduit une nouvelle propriété:
// An animatable property that can be used to adjust the maximum absolute width of the primary view controller in the split view controller.
@property(nonatomic, assign) CGFloat maximumPrimaryColumnWidth NS_AVAILABLE_IOS(8_0); // default: UISplitViewControllerAutomaticDimension
Utilisez cette propriété pour ajuster votre contrôleur de vue principal à la largeur souhaitée.
Voici comment j'ai fait cela dans iOS8 avec Swift.
class MainSplitViewController: UISplitViewController {
override func viewDidLoad() {
self.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
self.maximumPrimaryColumnWidth = 100 // specify your width here
}
}
Si vous devez modifier la largeur de manière dynamique à partir de votre vue principale/détaillée dans la vue fractionnée, procédez comme suit:
var splitViewController = self.splitViewController as MainSplitViewController
splitViewController.maximumPrimaryColumnWidth = 400
La manière de storyboard serait celle-ci, mentionnée par @Tim:
De plus, si vous souhaitez que la vue Maître occupe toujours un certain pourcentage de l'écran, vous pouvez utiliser le chemin clé = "preferredPrimaryColumnWidthFraction" et définir la valeur sur 0.2 (pour une taille d'écran de 20%).
Veuillez noter que "maximumPrimaryColumnWidth" est défini sur 320. Par conséquent, si vous essayez la valeur de pourcentage d'écran de 0,5 (50%), elle ne dépassera pas 320. Vous pouvez ajouter un chemin de clé pour maximumPrimaryColumnWidth si vous devez le remplacer.
Aucune des réponses ne fonctionnant pour moi sur iOS7, j'ai donc effectué certaines de mes recherches et créé une solution efficace. Cela impliquera de sous-classer UISplitViewController
pour toutes les fonctionnalités.
Je présenterai la réponse comme si nous venions de créer un nouveau projet pour iPad avec toutes les orientations du périphérique et de définir la variable personnalisée UISplitViewController
comme contrôleur de la vue principale.
Créez votre UISplitViewController
personnalisé. Dans cet exemple, le mien s'appelle MySplitViewController
. Tout le code sera basé sur MySplitViewController.m
.
Nous allons avoir besoin d'accéder à une méthode à partir de la UISplitViewControllerDelegate
donc ajoutez-la et définissez le délégué. Nous allons également configurer un transmetteur délégué si vous devez appeler les méthodes de délégation depuis une autre classe.
@interface MySplitViewController () <UISplitViewControllerDelegate>
@property (nonatomic, weak) id<UISplitViewControllerDelegate> realDelegate;
@end
@implementation MySplitViewController
- (instancetype)init {
self = [super init];
if (self) {
self.delegate = self;
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.delegate = self;
}
return self;
}
- (void)setDelegate:(id<UISplitViewControllerDelegate>)delegate {
[super setDelegate:nil];
self.realDelegate = (delegate != self) ? delegate : nil;
[super setDelegate:delegate ? self : nil];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
id delegate = self.realDelegate;
return [super respondsToSelector:aSelector] || [delegate respondsToSelector:aSelector];
}
- (id)forwardingTargetForSelector:(SEL)aSelector {
id delegate = self.realDelegate;
return [delegate respondsToSelector:aSelector] ? delegate : [super forwardingTargetForSelector:aSelector];
}
Configurez les contrôleurs de vue principale et de détail.
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController* masterViewController = [[UIViewController alloc] init];
masterViewController.view.backgroundColor = [UIColor yellowColor];
UIViewController* detailViewController = [[UIViewController alloc] init];
detailViewController.view.backgroundColor = [UIColor cyanColor];
self.viewControllers = @[masterViewController, detailViewController];
}
Ajoutons la largeur souhaitée à une méthode pour faciliter la référence.
- (CGFloat)desiredWidth {
return 200.0f;
}
Nous allons manipuler le contrôleur de vue principal avant de le présenter.
- (void)splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController {
id realDelegate = self.realDelegate;
if ([realDelegate respondsToSelector:@selector(splitViewController:popoverController:willPresentViewController:)]) {
[realDelegate splitViewController:svc popoverController:pc willPresentViewController:aViewController];
}
CGRect rect = aViewController.view.frame;
rect.size.width = [self desiredWidth];
aViewController.view.frame = rect;
aViewController.view.superview.clipsToBounds = NO;
}
Cependant, nous avons maintenant un écran comme celui-ci .
Alors allions remplacer une méthode privée. Oui, une méthode privée, il sera toujours acceptable dans l'App Store puisqu'il ne s'agit pas d'une méthode privée de soulignement.
- (CGFloat)leftColumnWidth {
return [self desiredWidth];
}
Cela concerne le mode portrait. Donc, une chose similaire pour -splitViewController:willShowViewController:invalidatingBarButtonItem:
et vous devriez être configuré pour le paysage.
Cependant, rien de tout cela ne sera nécessaire dans iOS8. Vous pourrez simplement appeler une propriété de largeur min et max!
Étant donné que personne n’a indiqué que cela pouvait être fait à partir d’IB, je voudrais ajouter cette réponse. Apparemment, vous pouvez définir des "attributs d'exécution définis par l'utilisateur" pour UISplitViewContorller avec les détails suivants:
utilisez le code suivant avant d’attribuer à rootviewcontroller. Cela fonctionne pour moi avec iOS 7
[self.splitViewController setValue:[NSNumber numberWithFloat:256.0] forKey:@"_masterColumnWidth"];
self.window.rootViewController = self.splitViewController;
Swift 3.0 vous utilisez comme
let widthfraction = 2.0 //Your desired value for me 2.0
splitViewController?.preferredPrimaryColumnWidthFraction = 0.40
let minimumWidth = min((splitViewController?.view.bounds.size.width)!,(splitViewController?.view.bounds.height)!)
splitViewController?.minimumPrimaryColumnWidth = minimumWidth / widthFraction
splitViewController?.maximumPrimaryColumnWidth = minimumWidth / widthFraction
let leftNavController = splitViewController?.viewControllers.first as! UINavigationController
leftNavController.view.frame = CGRect(x: leftNavController.view.frame.Origin.x, y: leftNavController.view.frame.Origin.y, width: (minimumWidth / widthFraction), height: leftNavController.view.frame.height)
Vous pouvez utiliser GSSplitViewController . Celui-ci fonctionnera sur iOS 7 et 8
splitView = [[GSSplitViewController alloc] init];
splitView.masterPaneWidth = 180;
Vous pouvez également l'inclure en ajoutant pod 'GSSplitViewController'
à votre Podfile
.
Dans mon cas, je devais définir le maximum et le minimum pour que cela fonctionne
mySplitViewController.preferredDisplayMode = .allVisible;
mySplitViewController.maximumPrimaryColumnWidth = UIScreen.main.bounds.width/2;
mySplitViewController.minimumPrimaryColumnWidth = UIScreen.main.bounds.width/2;