UIIMAGE ASPECT PAS PAS EN INACTEERD OP TOP

Het lijkt op aspect fitLijn de afbeelding standaard uit op de onderkant van het frame. Is er een weg naar Override de uitlijning terwijl u aspect fitintact?

** bewerken **

Deze vraag geeft automatische lay-out. In feite werd auto-indeling geopenbaard in WWDC 2012 dezelfde week deze vraag werd gesteld


Antwoord 1, Autoriteit 100%

Kortom, u kunt dit niet doen met een UIImageView.

Eén oplossing is om een ​​UIViewmet een UIImageViewte gebruiken en het frame volgens de afbeeldingsgrootte te wijzigen. U kunt bijvoorbeeld één versie hier vinden.


Antwoord 2, Autoriteit 52%

Zet de UIImageView‘S Bottom Layout Constraint Priority naar Laagste (d.w.z. 250) en het zal het voor u aan.


Antwoord 3, Autoriteit 44%

De manier om dit te doen is om de inhoud van de uiimageview-laag te wijzigen. De volgende code uit mijn project (subklasse van uiimageview) veronderstelt Scaletofill en compenseert de afbeelding zodanig dat het de bovenste, onderkant, links of rechts afstanden in plaats van de standaarduitlijning. Voor aspectfit is een vergelijkbare oplossing.

typedef NS_OPTIONS(NSUInteger, AHTImageAlignmentMode) {
    AHTImageAlignmentModeCenter = 0,
    AHTImageAlignmentModeLeft = 1 << 0,
    AHTImageAlignmentModeRight = 1 << 1,
    AHTImageAlignmentModeTop = 1 << 2,
    AHTImageAlignmentModeBottom = 1 << 3,
    AHTImageAlignmentModeDefault = AHTImageAlignmentModeCenter,
};
- (void)updateImageViewContentsRect {
    CGRect imageViewContentsRect = CGRectMake(0, 0, 1, 1);
    if (self.image.size.height > 0 && self.bounds.size.height > 0) {
        CGRect imageViewBounds = self.bounds;
        CGSize imageSize = self.image.size;
        CGFloat imageViewFactor = imageViewBounds.size.width / imageViewBounds.size.height;
        CGFloat imageFactor = imageSize.width / imageSize.height;
        if (imageFactor > imageViewFactor) {
            //Image is wider than the view, so height will match
            CGFloat scaledImageWidth = imageViewBounds.size.height * imageFactor;
            CGFloat xOffset = 0.0;
            if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeLeft)) {
                xOffset = -(scaledImageWidth - imageViewBounds.size.width) / 2;
            } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeRight)) {
                xOffset = (scaledImageWidth - imageViewBounds.size.width) / 2;
            }
            imageViewContentsRect.origin.x = (xOffset / scaledImageWidth);
        } else if (imageFactor < imageViewFactor) {
            CGFloat scaledImageHeight = imageViewBounds.size.width / imageFactor;
            CGFloat yOffset = 0.0;
            if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeTop)) {
                yOffset = -(scaledImageHeight - imageViewBounds.size.height) / 2;
            } else if (BM_CONTAINS_BIT(self.alignmentMode, AHTImageAlignmentModeBottom)) {
                yOffset = (scaledImageHeight - imageViewBounds.size.height) / 2;
            }
            imageViewContentsRect.origin.y = (yOffset / scaledImageHeight);
        }
    }
    self.layer.contentsRect = imageViewContentsRect;
}

SWIFT-versie

class AlignmentImageView: UIImageView {
    enum HorizontalAlignment {
        case left, center, right
    }
    enum VerticalAlignment {
        case top, center, bottom
    }
    // MARK: Properties
    var horizontalAlignment: HorizontalAlignment = .center
    var verticalAlignment: VerticalAlignment = .center
    // MARK: Overrides
    override var image: UIImage? {
        didSet {
            updateContentsRect()
        }
    }
    override func layoutSubviews() {
        super.layoutSubviews()
        updateContentsRect()
    }
    // MARK: Content layout
    private func updateContentsRect() {
        var contentsRect = CGRect(origin: .zero, size: CGSize(width: 1, height: 1))
        guard let imageSize = image?.size else {
            layer.contentsRect = contentsRect
            return
        }
        let viewBounds = bounds
        let imageViewFactor = viewBounds.size.width / viewBounds.size.height
        let imageFactor = imageSize.width / imageSize.height
        if imageFactor > imageViewFactor {
            // Image is wider than the view, so height will match
            let scaledImageWidth = viewBounds.size.height * imageFactor
            var xOffset: CGFloat = 0.0
            if case .left = horizontalAlignment {
                xOffset = -(scaledImageWidth - viewBounds.size.width) / 2
            }
            else if case .right = horizontalAlignment {
                xOffset = (scaledImageWidth - viewBounds.size.width) / 2
            }
            contentsRect.origin.x = xOffset / scaledImageWidth
        }
        else {
            let scaledImageHeight = viewBounds.size.width / imageFactor
            var yOffset: CGFloat = 0.0
            if case .top = verticalAlignment {
                yOffset = -(scaledImageHeight - viewBounds.size.height) / 2
            }
            else if case .bottom = verticalAlignment {
                yOffset = (scaledImageHeight - viewBounds.size.height) / 2
            }
            contentsRect.origin.y = yOffset / scaledImageHeight
        }
        layer.contentsRect = contentsRect
    }
}

Antwoord 4, autoriteit 40%

dit zorgt ervoor dat de afbeelding de breedte vult en alleen de hoogte inneemt die nodig is om in de afbeelding te passen (breed gesproken)

snel 4.2:

let image = UIImage(named: "my_image")!
let ratio = image.size.width / image.size.height
cardImageView.widthAnchor
  .constraint(equalTo: cardImageView.heightAnchor, multiplier: ratio).isActive = true

Antwoord 5, autoriteit 8%

Ik had een soortgelijk probleem.
De eenvoudigste manier was om een ​​eigen subklasse van UIImageView te maken. Ik voeg voor subklasse 3 eigenschappen toe, zodat het nu gemakkelijk kan worden gebruikt zonder de interne implementatie te kennen:

@property (nonatomic) LDImageVerticalAlignment imageVerticalAlignment;
@property (nonatomic) LDImageHorizontalAlignment imageHorizontalAlignment;
@property (nonatomic) LDImageContentMode imageContentMode;

Je kunt het hier controleren:
https://github.com/LucasssD/LDAlignmentImageView


Antwoord 6, autoriteit 8%

  1. Voeg de Aspect Ratio-beperking toe aan uw afbeeldingsverhoudingen.
  2. Plaats UIImageView niet onderaan vast.
  3. Als u de UIImage dynamisch wilt wijzigen, denk er dan aan om de beperking van de beeldverhouding bij te werken.

Antwoord 7

Ik heb dit standaard opgelost in Interface Builder door een beperking in te stellen op de hoogte van de UIImageView, aangezien de afbeelding altijd omhoog zou worden ‘geduwd’ als de afbeelding groter was dan de schermgrootte.

Meer specifiek heb ik de UIImageView op dezelfde hoogte ingesteld als de weergave waarin deze zich bevindt (via hoogtebeperking), en vervolgens de UIImageView met afstandsbeperkingen in IB geplaatst. Dit resulteert erin dat de UIImageView een ‘Aspect Fit’ heeft die nog steeds de bovenste afstandsbeperking respecteert die ik in IB heb ingesteld.


Antwoord 8

Als u UIImageViewkunt subclasseren, kunt u de imagevar gewoon overschrijven.

override var image: UIImage? {
    didSet {
        self.sizeToFit()
    }
}

In Objective-C kun je hetzelfde doen door de setter te negeren.

Other episodes