iphone - values - uipickerview swift 4




Comment changer la hauteur de UIPickerView (18)

Avantages:

  1. Rend le setFrame de UIPickerView se comporter comme il se doit
  2. Aucun code de transformation dans votre UIViewController
  3. Fonctionne dans viewWillLayoutSubviews pour redimensionner / positionner l' UIPickerView
  4. Fonctionne sur l'iPad sans UIPopover
  5. La superclasse reçoit toujours une hauteur valide
  6. Fonctionne avec iOS 5

Désavantages:

  1. Vous UIPickerView à sous- UIPickerView
  2. Nécessite l'utilisation de pickerView viewForRow pour annuler la transformation pour les sous-vues
  3. UIAnimations pourrait ne pas fonctionner

Solution:

Sous-classe UIPickerView et remplacer les deux méthodes en utilisant le code suivant. Il combine le sous-classement, la hauteur fixe et l'approche de la transformation.

#define FIXED_PICKER_HEIGHT 216.0f
- (void) setFrame:(CGRect)frame
{
    CGFloat targetHeight = frame.size.height;
    CGFloat scaleFactor = targetHeight / FIXED_PICKER_HEIGHT;
    frame.size.height = FIXED_PICKER_HEIGHT;//fake normal conditions for super
    self.transform = CGAffineTransformIdentity;//fake normal conditions for super
    [super setFrame:frame];
    frame.size.height = targetHeight;
    CGFloat dX=self.bounds.size.width/2, dY=self.bounds.size.height/2;
    self.transform = CGAffineTransformTranslate(CGAffineTransformScale(CGAffineTransformMakeTranslation(-dX, -dY), 1, scaleFactor), dX, dY);
}

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    //Your code goes here

    CGFloat inverseScaleFactor = FIXED_PICKER_HEIGHT/self.frame.size.height;
    CGAffineTransform scale = CGAffineTransformMakeScale(1, inverseScaleFactor);
    view.transform = scale;
    return view;
}

Est-il possible de changer la hauteur de UIPickerView? Certaines applications semblent avoir PickerViews plus courtes, mais la définition d'une image plus petite ne semble pas fonctionner et le cadre est verrouillé dans Interface Builder.


Après une longue journée à me gratter la tête, j'ai trouvé quelque chose qui fonctionne pour moi. Les codes ci-dessous vont recréer le UIDatePicker chaque fois que l'utilisateur change l'orientation du téléphone. Cela supprimera tout problème rencontré par le UIDatePicker après un changement d'orientation.

Puisque nous recréons le UIDatePicker, nous avons besoin d'une variable d'instance qui gardera la valeur de date sélectionnée. Les codes ci-dessous sont testés sur iOS 4.0.

    @interface AdvanceDateViewController : UIViewController<UIPickerViewDelegate> {
        UIDatePicker *datePicker;
        NSDate *date;
    }


    @property (nonatomic, retain) UIDatePicker *datePicker;
    @property (nonatomic, retain) NSDate *date;

    -(void)resizeViewWithOrientation:(UIInterfaceOrientation) orientation;

    @end

    @implementation AdvanceDateViewController
    @synthesize datePicker, date;

    - (void)viewDidLoad {
      [super viewDidLoad];
          [self resizeViewWithOrientation:self.interfaceOrientation];
    }


    -(void)viewWillAppear:(BOOL)animated{
         [super viewWillAppear:animated];
         [self resizeViewWithOrientation:self.interfaceOrientation];
     }

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
         return YES;
     }

     -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
      [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
      [self resizeViewWithOrientation:toInterfaceOrientation];
      }

     -(void)resizeViewWithOrientation:(UIInterfaceOrientation) orientation{
          [self.datePicker removeFromSuperview];
          [self.datePicker removeTarget:self action:@selector(refreshPickupDate) forControlEvents:UIControlEventValueChanged];
          self.datePicker = nil;

          //(Re)initialize the datepicker, thanks to Apple's buggy UIDatePicker implementation
          UIDatePicker *dummyDatePicker = [[UIDatePicker alloc] init];
          self.datePicker = dummyDatePicker;
          [dummyDatePicker release];

          [self.datePicker setDate:self.date animated:YES];
          [self.datePicker addTarget:self action:@selector(refreshPickupDate) forControlEvents:UIControlEventValueChanged];

          if(UIInterfaceOrientationIsLandscape(orientation)){
                 self.datePicker.frame = CGRectMake(0, 118, 480, 162);    
           } else {
                 self.datePicker.frame = CGRectMake(0, 200, 320, 216);
           }

           [self.view addSubview:self.datePicker];
           [self.view setNeedsDisplay];
      }

      @end

Cela a beaucoup changé dans iOS 9 (dans iOS 8, c'est assez similaire à ce que nous voyons ici). Si vous pouvez vous permettre de cibler iOS 9 uniquement, vous pouvez redimensionner UIPickerView comme bon vous semble, en définissant son cadre. Bien!

Ici, il vient de iOS 9 Notes de publication

UIPickerView et UIDatePicker sont maintenant redimensionnables et adaptatifs. Auparavant, ces vues appliquaient une taille par défaut même si vous essayiez de les redimensionner. Ces points de vue ont également par défaut une largeur de 320 points sur tous les périphériques, au lieu de la largeur de l'appareil sur iPhone.

Les interfaces qui reposent sur l'ancienne implémentation de la taille par défaut sembleront probablement incorrectes lors de la compilation pour iOS 9. Tous les problèmes rencontrés peuvent être résolus en limitant ou en dimensionnant complètement les vues du sélecteur à la taille souhaitée au lieu de s'appuyer sur un comportement implicite.


Créer une vue dans IB ou code. Ajoutez votre sélecteur en tant que sous-vue de cette vue. Redimensionner la vue C'est le plus facile à faire dans IB. Créez des contraintes de la vue à sa vue d'ensemble et du sélecteur à cette nouvelle vue.

Puisque les courbes de Picker autour de lui déborde sur le haut et le bas de la vue. Vous pouvez voir dans IB lorsque vous ajoutez des contraintes top et bottom du sélecteur à la vue. Cela affiche un espace standard de 16 points au-dessus et au-dessous du conteneur superview. Définissez l'affichage pour le découper si vous ne voulez pas ce comportement (avertissement moche).

Voici à quoi ça ressemble à 96 points de haut sur un iPhone 5. Le sélecteur avec le débordement est d'environ 130 points de haut. Assez maigre!

J'utilise ceci dans mon projet pour empêcher le sélecteur de s'étaler à une taille inutile. Cette technique l'atténue et force un déversement plus serré. Il semble effectivement plus lisse pour être un peu plus compact.

Voici une image de la vue montrant le débordement.

Voici les contraintes IB que j'ai ajoutées.


Dans iOS 5.0, j'ai obtenu ce qui suit pour fonctionner:

UIDatePicker *picker = [[UIDatePicker alloc] init];
picker.frame = CGRectMake(0.0, 0.0, 320.0, 160.0);

Cela a créé un sélecteur de date comme celui utilisé par Apple dans l'application Calendrier lors de la création d'un nouvel événement en mode paysage. (3 lignes de hauteur au lieu de 5.) Cela ne fonctionnait pas lorsque je définissais le cadre dans la méthode initWithFrame: mais fonctionne jusqu'à présent lorsque vous le définissez en utilisant une méthode séparée.


Depuis iOS 9, vous pouvez modifier librement la largeur et la hauteur de UIPickerView . Pas besoin d'utiliser les hacks de transformation mentionnés ci-dessus.


Il n'y a que trois hauteurs valides pour UIPickerView (162.0, 180.0 and 216.0) .

Vous pouvez utiliser les fonctions CGAffineTransformMakeTranslation et CGAffineTransformMakeScale pour adapter correctement le sélecteur à votre convenance.

Exemple:

CGAffineTransform t0 = CGAffineTransformMakeTranslation (0, pickerview.bounds.size.height/2);
CGAffineTransform s0 = CGAffineTransformMakeScale       (1.0, 0.5);
CGAffineTransform t1 = CGAffineTransformMakeTranslation (0, -pickerview.bounds.size.height/2);
pickerview.transform = CGAffineTransformConcat          (t0, CGAffineTransformConcat(s0, t1));

Le code ci-dessus change la hauteur de la vue du sélecteur à la moitié et la repositionne à la position exacte (Left-x1, Top-y1) .


Incorporer dans une vue de la pile. La vue Stack est un composant récemment ajouté par Apple dans son SDK iOS pour refléter les implémentations basées sur une grille dans les bibliothèques frontales basées sur le Web Java Script telles que bootstrap.


J'utilise un calque de masque pour changer sa taille d'affichage

// swift 3.x
let layer = CALayer()
layer.frame = CGRect(x: 0,y:0, width: displayWidth, height: displayHeight)
layer.backgroundColor = UIColor.red.cgColor
pickerView.layer.mask = layer

Je n'ai pas pu suivre l'un des conseils ci-dessus.

J'ai regardé plusieurs tutoriels et trouvé this ci le plus bénéfique:

J'ai ajouté le code suivant pour définir la nouvelle hauteur à l'intérieur de la méthode "viewDidLoad", qui a fonctionné dans mon application.

UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)]; 
[self.view addSubview:picker];
picker.delegate = self;
picker.dataSource = self;

J'espère que cela a été utile!


Même si vous pensez qu'il n'est pas redimensionné, une autre astuce peut aider dans la situation où l'UIPicker est situé au bas de l'écran.

On peut essayer de le déplacer légèrement vers le bas, mais la rangée centrale doit rester visible. Cela aidera à révéler un peu d'espace au-dessus du sélecteur puisque les lignes du bas seront hors écran.

Je répète que ce n'est pas la manière de changer la hauteur de la vue UIPicker mais une idée sur ce que vous pouvez faire si toutes les autres tentatives échouent.


Mon truc: utilisez le calque du masque de datepicker pour rendre visible une partie de datePicker. comme vous voyez, tout comme changer le cadre de la datepicke.

- (void)timeSelect:(UIButton *)timeButton {
UIDatePicker *timePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 550)];
timePicker.backgroundColor = [UIColor whiteColor];
timePicker.layer.mask = [self maskLayerWithDatePicker:timePicker];
timePicker.layer.masksToBounds = YES;
timePicker.datePickerMode = UIDatePickerModeTime;
[self.view addSubview:timePicker];
}

- (CALayer *)maskLayerWithDatePicker:(UIDatePicker *)datePicker {
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, datePicker.width*0.8, datePicker.height*0.8) cornerRadius:10];
shapeLayer.path = path.CGPath;
return shapeLayer;
}

Pour autant que je sache, il est impossible de réduire l'UIPickerView. Je n'ai pas non plus vu un plus court utilisé n'importe où. Je suppose que c'est une implémentation personnalisée si elles ont réussi à le réduire.


Si vous voulez créer votre sélecteur dans IB, vous pouvez le redimensionner à une taille plus petite. Vérifiez pour vous assurer qu'il dessine toujours correctement, car il arrive un moment où il semble odieux.



Vous ne pouvez généralement pas le faire en xib ou en paramétrant le cadre mais si vous ouvrez son parent xib comme source et changez la hauteur à partir de là alors ça marche. Cliquez droit sur le xib dans lequel pickerview est contenu, Search pickerview et vous pouvez trouver la hauteur, la largeur etc Dans cette balise, Changez la hauteur puis sauvegardez le fichier.

<pickerView contentMode="scaleToFill" id="pai-pm-hjZ">
                                    <rect key="frame" x="0.0" y="41" width="320" height="100"/>
                                    <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
                                    <connections>
                                        <outlet property="dataSource" destination="-1" id="Mo2-zp-Sl4"/>
                                        <outlet property="delegate" destination="-1" id="nfW-lU-tsU"/>
                                    </connections>
                                </pickerView>

Swift : Vous devez ajouter une sous-vue avec clip aux limites

    var DateView = UIView(frame: CGRectMake(0, 0, view.frame.width, 100))
    DateView.layer.borderWidth=1
    DateView.clipsToBounds = true

    var myDatepicker = UIDatePicker(frame:CGRectMake(0,-20,view.frame.width,162));
    DateView.addSubview(myDatepicker);
    self.view.addSubview(DateView)

Cela devrait ajouter un sélecteur de date taille 100 écrêté dans le haut du contrôleur de vue.


Il semble évident qu'Apple n'invite pas particulièrement le déblaiement avec la hauteur par défaut de UIPickerView , mais j'ai constaté que vous pouvez modifier la hauteur de la vue en prenant le contrôle complet et en passant une taille d'image souhaitée au moment de la création, par exemple :

smallerPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 120.0)];

Vous découvrirez qu'à différentes hauteurs et largeurs, il y a des défauts visuels. Évidemment, ces défauts devraient soit être travaillés d'une manière ou d'une autre, ou choisir une autre taille qui ne les présente pas.







uipickerview