J'ai la sous-classe UIView et pour la mise en page des éléments de l'interface utilisateur, je n'utilise pas la mise en page automatique. Je veux définir le cadre dépend de la largeur ou de la hauteur du cadre. Cependant, quand je fais cela juste après les méthodes alloc]init], cela ressemble à self.frame.size.height ou width vaut zéro. Pour une solution temporaire, j'ai fait ce qui suit:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.25 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        UIImage *img = [UIImage imageNamed:@"sound_level_arrow"];
        _arrowImgView = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width/2, 0, img.size.width, img.size.height)];
        _arrowImgView.center = CGPointMake(self.mainImgView.frame.size.width/2, self.mainImgView.frame.size.height-2);
        _arrowImgView.image = [UIImage imageNamed:@"sound_level_arrow"];
        _arrowImgView.contentMode   = UIViewContentModeCenter;
        [self.mainImgView addSubview:_arrowImgView];
    });

Mais bien sûr, j'ai besoin de savoir quand la vue a fini de se charger et où elle a réellement self.frame.size.width et height.

11
Evgeniy Kleban 20 avril 2017 à 16:51

3 réponses

Meilleure réponse

Si vous souhaitez effectuer cette opération dans votre sous-classe de vue personnalisée, remplacez layoutSubviews dans cette classe. Étant donné qu'iOS peut envoyer layoutSubviews plusieurs fois, veillez à ne créer _arrowImgView que la première fois:

- (void)layoutSubviews {
    [super layoutSubviews];

    if (_arrowImgView == nil) {
        UIImage *image = [UIImage imageNamed:@"sound_level_arrow"];
        _arrowImgView = [[UIImageView alloc] initWithImage:image];
        _arrowImgView.contentMode = UIViewContentModeCenter;
        [self addSubview:_arrowImgView];
    }

    CGRect myBounds = self.bounds;
    CGRect mainFrame = self.mainImageView.frame;
    _arrowImgView.bounds = CGRectMake(0, 0, myBounds.size.width, myBounds.size.height);
    _arrowImgView.center = CGPointMake(mainFrame.size.width / 2, mainFrame.size.height - 2);
}
15
rob mayoff 20 avril 2017 à 14:13

ViewWillLayoutSubviews et un dernier viewDidLayoutSubviews

- (void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
   // your code for positioning any subview here
}
-7
Iulian Onofrei 15 févr. 2018 à 10:01

Utilisez celui-ci. Il gère les changements d'orientation et le rafraîchissement de l'arrière-plan dégradé.

import UIKit

@IBDesignable
final class GradientButton: UIButton {

    @IBInspectable var startColor: UIColor = UIColor.clear
    @IBInspectable var endColor: UIColor = UIColor.clear

    override func draw(_ rect: CGRect) {

        if let gradient = layer.sublayers?.first as? CAGradientLayer {
            gradient.removeFromSuperlayer()
        }

        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.frame = CGRect(origin: CGPoint.zero, size: self.frame.size)
        gradient.colors = [startColor.cgColor, endColor.cgColor]
        layer.insertSublayer(gradient, at: 0)

        super.draw(rect)
    }

   @IBInspectable var imageContentMode: Int {
        get {
            return imageView?.contentMode.rawValue ?? 0
        }
        set {
            imageView?.contentMode = UIViewContentMode(rawValue: newValue) ?? .scaleAspectFit

        }
    }
}
4
Michał Ziobro 20 avril 2018 à 10:36