Home > Mobile >  Disable anti-aliasing in UIKit (swift)
Disable anti-aliasing in UIKit (swift)

Time:07-01

I've got a pixel art game app that uses UIKit for its menus and SpriteKit for the gameplay scene. The pixels are getting blurred due to anti-aliasing.

With the sprites I can turn off the anti-aliasing using...

    node.texture?.filteringMode = .nearest

but in UIKit I can't find a way to turn off the anti-aliasing in the UIImageView's.

I saw this post but there's no example and the answer wasn't accepted. Not sure how to turn it off using CGContextSetShouldAntialias, or where to call it.

Based on the example I found here, tried using this sub-class but it didn't seem to make a difference; according to my breakpoints the method is never called:

class NonAliasingView: UIImageView {

 override func draw(_ rect: CGRect) {
   guard let ctx = UIGraphicsGetCurrentContext() else { return }
  
   // fill background with black color
   ctx.addRect(bounds)
   ctx.setFillColor(UIColor.black.cgColor)
   ctx.fillPath()
   
   if let img = image {
     let pixelSize = CGSize(width: img.size.width * layer.contentsScale, height: img.size.height * layer.contentsScale)
     UIGraphicsBeginImageContextWithOptions(pixelSize, true, 1)

     guard let imgCtx = UIGraphicsGetCurrentContext() else { return }
     imgCtx.setShouldAntialias(false)
     img.draw(in: CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height))

     guard let cgImg = imgCtx.makeImage() else { return }
     ctx.scaleBy(x: 1, y: -1)
     ctx.translateBy(x: 0, y: -bounds.height)

     ctx.draw(cgImg, in: CGRect(x: (bounds.width - img.size.width) / 2, y: (bounds.height - img.size.height) / 2, width: img.size.width, height: img.size.height))
   }
 }
}

Here's the code from my view controller where I tried to implement the sub class (modeImage is an IBOutlet to an UIImageView):

//    modeImage.image = gameMode.displayImage
    
    let modeImg = NonAliasingView()
    modeImg.image = gameMode.displayImage
    modeImage = modeImg

If I try to use UIGraphicsGetCurrentContext in the view controller it is nil and never passes the guard statement.

I've confirmed view.layer.allowsEdgeAntialiasing defaults to false. I don't need anti-aliasing at all, so if there's a way to turn off anti-aliasing app wide, or in the whole view controller, I'd be happy to use it.

How do you disable anti-aliasing with an UIImageView in UIKit?

UPDATE

Added imgCtx.setShouldAntialias(false) to method but still not working.

CodePudding user response:

To remove all antialiasing on your image view and just use nearest-neighbor filtering, set the magnificationFilter and minificationFilter of the image view's layer to CALayerContentsFilter.nearest, as in:

yourImageView.layer.magnificationFilter = .nearest
yourImageView.layer.minificationFilter = .nearest
  • Related