NSImageView Bildaspekt füllen?
-
20-12-2019 - |
Frage
Also bin ich es gewohnt UIImageView
, und in der Lage zu sein, verschiedene Arten festzulegen, wie sein Bild darin angezeigt wird.Wie zum Beispiel AspectFill
modus usw...
Ich möchte das gleiche erreichen mit NSImageView
auf einer Mac-App.Tun NSImageView
funktioniert ähnlich wie UIImageView
in dieser Hinsicht oder wie würde ich vorgehen, um ein Bild in einem zu zeigen NSImageView
und verschiedene Arten der Darstellung dieses Bildes auswählen?
Lösung
Möglicherweise fällt es Ihnen viel leichter, Unterklassen zu bilden NSView
und bieten eine CALayer
das füllt den Aspekt für Sie aus.Hier ist, was die init
könnte so aussehen NSView
Subklasse.
- (id)initWithFrame:(NSRect)frame andImage:(NSImage*)image
{
self = [super initWithFrame:frame];
if (self) {
self.layer = [[CALayer alloc] init];
self.layer.contentsGravity = kCAGravityResizeAspectFill;
self.layer.contents = image;
self.wantsLayer = YES;
}
return self;
}
Beachten Sie, dass die Reihenfolge der Einstellung der Ebene, dann Einstellungen wantsLayer ist sehr wichtig (wenn Sie zuerst wantsLayer festlegen, erhalten Sie stattdessen eine Standard-Hintergrundebene).
Sie könnten eine haben setImage
methode, die einfach den Inhalt der Ebene aktualisiert.
Andere Tipps
Ich hatte das gleiche Problem.Ich wollte, dass das Bild so skaliert wird, dass es gefüllt wird, aber das Seitenverhältnis des Originalbildes beibehalten wird.Seltsamerweise ist dies nicht so einfach, wie es scheint, und wird mit NSImageView nicht sofort ausgeliefert.Ich wollte, dass die NSImageView schön skaliert wird, während sie mit Superview (s) in der Größe geändert wird.Ich habe eine Drop-In-NSImageView-Unterklasse erstellt, die Sie auf Github finden können: KPCSCALETOFILLNBILDANSICHT
Sie können dies verwenden:das Bild wird gezwungen, die Ansichtsgröße zu füllen
(Aspektfüllung)
imageView.imageScaling = .scaleAxesIndependently
(Aspektanpassung)
imageView.imageScaling = .scaleProportionallyUpOrDown
(Mitte oben)
imageView.imageScaling = .scaleProportionallyDown
Es funktioniert für mich.
Hier ist, was ich benutze, geschrieben mit Swift.Dieser Ansatz funktioniert gut mit Storyboards - verwenden Sie einfach eine normale NSImageView und ersetzen Sie dann den Namen NSImageView im Klassenfeld durch MyAspectFillImageNSImageView ...
open class MyAspectFillImageNSImageView : NSImageView {
open override var image: NSImage? {
set {
self.layer = CALayer()
self.layer?.contentsGravity = kCAGravityResizeAspectFill
self.layer?.contents = newValue
self.wantsLayer = true
super.image = newValue
}
get {
return super.image
}
}
}
Zum Bekommen AspectFit
eigentum von UIImageView
in Kakao NSImageView
habe diese Methode
[imageView setImageScaling:NSScaleProportionally];
Hier finden Sie weitere Optionen zum Ändern der Bildanzeigeeigenschaft.
enum {
NSScaleProportionally = 0, // Deprecated. Use NSImageScaleProportionallyDown
NSScaleToFit, // Deprecated. Use NSImageScaleAxesIndependently
NSScaleNone // Deprecated. Use NSImageScaleNone
};
Es fiel mir schwer herauszufinden, wie man eine machen kann Aspektfüllungsclip an Grenzen :
Bildnachweis: https://osxentwicklerforum.de/index.php/Thread/28812-NSImageView-Scaling-Seitenverh%C3%A4ltnis/
Endlich habe ich meine eigene Unterklasse von NSImageView erstellt, hoffe, das kann jemandem helfen :
import Cocoa
@IBDesignable
class NSImageView_ScaleAspectFill: NSImageView {
@IBInspectable
var scaleAspectFill : Bool = false
override func awakeFromNib() {
// Scaling : .scaleNone mandatory
if scaleAspectFill { self.imageScaling = .scaleNone }
}
override func draw(_ dirtyRect: NSRect) {
if scaleAspectFill, let _ = self.image {
// Compute new Size
let imageViewRatio = self.image!.size.height / self.image!.size.width
let nestedImageRatio = self.bounds.size.height / self.bounds.size.width
var newWidth = self.image!.size.width
var newHeight = self.image!.size.height
if imageViewRatio > nestedImageRatio {
newWidth = self.bounds.size.width
newHeight = self.bounds.size.width * imageViewRatio
} else {
newWidth = self.bounds.size.height / imageViewRatio
newHeight = self.bounds.size.height
}
self.image!.size.width = newWidth
self.image!.size.height = newHeight
}
// Draw AFTER resizing
super.draw(dirtyRect)
}
}
Plus das ist @IBDesignable
so können Sie es im StoryBoard einstellen
UNWETTERWARNUNGEN
Ich bin neu in der schnellen macOS-Entwicklung, ich komme aus der iOS-Entwicklung, deshalb war ich überrascht, dass ich keine finden konnte clipToBound eigentum, vielleicht existiert es und ich konnte es nicht finden!
In Bezug auf den Code vermute ich, dass dies viel kostet, und dies hat auch den Nebeneffekt, dass das ursprüngliche Bildverhältnis im Laufe der Zeit geändert wird.Diese Nebenwirkung schien mir vernachlässigbar.
Noch einmal, wenn es eine Einstellung ist, die a erlaubt NSImageView
um an Grenzen zu befestigen, entfernen Sie bitte diese Antwort :]