¿Relleno de aspecto de imagen NSImageView?
-
20-12-2019 - |
Pregunta
Entonces estoy acostumbrado a UIImageView
, y poder configurar diferentes formas de cómo se muestra su imagen en él.Como por ejemplo AspectFill
modo, etc...
Me gustaría lograr lo mismo usando NSImageView
en una aplicación de mac.Hace NSImageView
trabajar de manera similar a UIImageView
en ese sentido o ¿cómo haría para mostrar una imagen en un NSImageView
¿Y elegir diferentes formas de mostrar esa imagen?
Solución
Puede que le resulte mucho más fácil subclasificar NSView
y proporcionar un CALayer
eso llena el aspecto para ti.Esto es lo que init
podría verse así NSView
subclase.
- (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;
}
Tenga en cuenta que el orden de configuración de la capa, luego la configuración wantLayer es muy importante (Si configuras wantLayer primero, obtendrás una capa de respaldo predeterminada).
Podrías tener un setImage
método que simplemente actualiza el contenido de la capa.
Otros consejos
Yo tuve el mismo problema.Quería escalar la imagen para llenarla pero manteniendo la relación de aspecto de la imagen original.Curiosamente, esto no es tan simple como parece y no viene incluido con NSImageView.Quería que NSImageView se escalara bien mientras cambiaba de tamaño con las supervistas.Hice una subclase NSImageView que puedes encontrar en github: KPCScaleToFillNSImageView
Puedes usar esto:La imagen se verá obligada a llenar el tamaño de la vista.
(Relleno de aspecto)
imageView.imageScaling = .scaleAxesIndependently
(Ajuste de aspecto)
imageView.imageScaling = .scaleProportionallyUpOrDown
(Centro superior)
imageView.imageScaling = .scaleProportionallyDown
Esto funciona para mi.
Esto es lo que estoy usando, escrito con Swift.Este enfoque funciona bien con guiones gráficos: simplemente use un NSImageView normal, luego reemplace el nombre NSImageView en el cuadro Clase, con 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
}
}
}
por conseguir AspectFit
propiedad de UIImageView
en cacao NSImageView
tener este método
[imageView setImageScaling:NSScaleProportionally];
Aquí hay más opciones para cambiar la propiedad de visualización de la imagen.
enum {
NSScaleProportionally = 0, // Deprecated. Use NSImageScaleProportionallyDown
NSScaleToFit, // Deprecated. Use NSImageScaleAxesIndependently
NSScaleNone // Deprecated. Use NSImageScaleNone
};
Me estaba costando mucho intentar descubrir cómo se puede hacer una Relleno de aspecto Recortar hasta límites :
Crédito de la imagen: https://osxentwicklerforum.de/index.php/Thread/28812-NSImageView-Scaling-Seitenverh%C3%A4ltnis/
Finalmente hice mi propia subclase de NSImageView, espero que esto pueda ayudar a alguien:
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)
}
}
Además esto es @IBDesignable
para que puedas configurarlo en el StoryBoard
ADVERTENCIAS
Soy nuevo en el desarrollo de MacOS Swift, vengo del desarrollo de iOS, por eso me sorprendió no poder encontrar un clipToBound propiedad, tal vez existe y no pude encontrarla!
Con respecto al código, sospecho que esto consume mucho y también tiene el efecto secundario de modificar la proporción de la imagen original con el tiempo.Este efecto secundario me pareció insignificante.
Una vez más, si hay una configuración que permite una NSImageView
para recortar los límites, elimine esta respuesta :]