NSImageView图像方面填充?

问题描述 投票:15回答:6

所以我习惯了UIImageView,能够设置不同的图像显示方式。比如AspectFill模式等......

我想在mac应用程序上使用NSImageView完成同样的事情。 NSImageView在这方面是否与UIImageView的工作方式类似,或者我如何在NSImageView中展示图像并选择不同的方式来显示该图像?

macos nsimageview
6个回答
22
投票

您可能会发现将NSView子类化并提供一个为您填充方面填充的CALayer更容易。以下是这个init子类的NSView可能是什么样子。

- (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;
}

请注意,设置图层的顺序,然后设置wantsLayer非常重要(如果先设置wantsLayer,则会获得默认的背衬层)。

您可以使用setImage方法简单地更新图层的内容。


13
投票

我有同样的问题。我希望缩放图像以填充,但保持原始图像的纵横比。奇怪的是,这并不像看起来那么简单,并且没有开箱即用的NSImageView。我希望NSImageView在使用superview(s)调整大小时能够很好地扩展。我在github:KPCScaleToFillNSImageView上找到了一个可插入的NSImageView子类


5
投票

你可以使用这个:图像将强制填充视图大小 (Aspect填充)

imageView.imageScaling = .scaleAxesIndependently

(Aspect Fit)

imageView.imageScaling = .scaleProportionallyUpOrDown

(中心顶部)

imageView.imageScaling = .scaleProportionallyDown

这个对我有用。


4
投票

这是我正在使用的,用Swift编写的。这种方法适用于故事板 - 只需使用普通的NSImageView,然后使用MyAspectFillImageNSImageView替换类框中的名称NSImageView ...

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
    }
  }
}

1
投票

在Cocoa AspectFit获得UIImageViewNSImageView属性有这种方法

[imageView setImageScaling:NSScaleProportionally];

以下是更改图像显示属性的更多选项。

enum {
    NSScaleProportionally = 0, // Deprecated. Use NSImageScaleProportionallyDown
    NSScaleToFit,              // Deprecated. Use NSImageScaleAxesIndependently
    NSScaleNone                // Deprecated. Use NSImageScaleNone
};

0
投票

我很难弄清楚如何制作Aspect Fill Clip to Bounds:

Credit : https://osxentwicklerforum.de/index.php/Thread/28812-NSImageView-Scaling-Seitenverh%C3%A4ltnis/图片来源:https://osxentwicklerforum.de/index.php/Thread/28812-NSImageView-Scaling-Seitenverh%C3%A4ltnis/

最后我创建了自己的NSImageView子类,希望这可以帮助某人:

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)
    }
}

另外这是@IBDesignable所以你可以在StoryBoard中设置它

警告

  • 我是MacOS Swift开发的新手,我来自iOS开发,这就是为什么我很惊讶我找不到clipToBound属性,也许它存在而且我无法找到它!
  • 关于代码,我怀疑这会消耗很多,而且这也会产生随时修改原始图像比例的副作用。这种副作用对我来说似乎微不足道。

如果他们的设置允许NSImageView剪辑到界限,请再次删除此答案:]

© www.soinside.com 2019 - 2024. All rights reserved.