ios - 在 Swift 中以编程方式设置时配置文件选项卡栏图像像素化

标签 ios swift uitabbarcontroller

我试图在从用户的数据库条目下载后将配置文件图像设置到选项卡栏。为此,我必须使用以下方法手动将图像裁剪为 35x35,使其不大于条形:

func crop(to: CGSize) -> UIImage {

        guard let cgimage = self.cgImage else { return self }

        let contextImage: UIImage = UIImage(cgImage: cgimage)

        guard let newCgImage = contextImage.cgImage else { return self }

        let contextSize: CGSize = contextImage.size

        //Set to square
        var posX: CGFloat = 0.0
        var posY: CGFloat = 0.0
        let cropAspect: CGFloat = to.width / to.height

        var cropWidth: CGFloat = to.width
        var cropHeight: CGFloat = to.height

        if to.width > to.height { //Landscape
            cropWidth = contextSize.width
            cropHeight = contextSize.width / cropAspect
            posY = (contextSize.height - cropHeight) / 2
        } else if to.width < to.height { //Portrait
            cropHeight = contextSize.height
            cropWidth = contextSize.height * cropAspect
            posX = (contextSize.width - cropWidth) / 2
        } else { //Square
            if contextSize.width >= contextSize.height { //Square on landscape (or square)
                cropHeight = contextSize.height
                cropWidth = contextSize.height * cropAspect
                posX = (contextSize.width - cropWidth) / 2
            }else{ //Square on portrait
                cropWidth = contextSize.width
                cropHeight = contextSize.width / cropAspect
                posY = (contextSize.height - cropHeight) / 2
            }
        }

        let rect: CGRect = CGRect(x: posX, y: posY, width: cropWidth, height: cropHeight)

        // Create bitmap image from context using the rect
        guard let imageRef: CGImage = newCgImage.cropping(to: rect) else { return self}

        // Create a new image based on the imageRef and rotate back to the original orientation
        let cropped: UIImage = UIImage(cgImage: imageRef, scale: self.scale, orientation: self.imageOrientation)

        UIGraphicsBeginImageContextWithOptions(to, false, self.scale)
        cropped.draw(in: CGRect(x: 0, y: 0, width: to.width, height: to.height))
        let resized = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return resized ?? self
    }

像这样在标签栏中调用我的“setViewControllers”方法:

func setViewControllers() {

//.......
    let profileImage: UIImage = (UserManager.current?.profileImage?.crop(to: CGSize(width: 35, height: 35)).roundedImage ?? #imageLiteral(resourceName: "profile_tab_bar_icon.png")).withRenderingMode(.alwaysOriginal)Ca

    let profileNavBarController = createViewController(identifier: "ProfileNavigationController", storyboardName: "Profile", tabBarImage: profileImage)

    profileNavBarController.tabBarItem.imageInsets = UIEdgeInsets(top: 9, left: 0, bottom: -9, right: 0)

    self.viewControllers = [foo, bar, profileNavBarController]
}

显然,这不适用于视网膜,因为我无法设置@2X 和@3X 版本。因此,图像在标签栏中被像素化了:

Pixelated tab image

我尝试将图像大小设置为 70x70,这显然会返回不适合标签栏的图像。我还研究了一种使用@2X 和@3X 创建 UIImage 对象的方法,但一无所获。

关于如何解决这个问题有什么想法吗?

最佳答案

将以下扩展添加到您的项目中,您可以在 ViewController.swift 类结束后添加。

extension UITabBarController {
    
    func addSubviewToLastTabItem(_ imageName: String) {
        if let lastTabBarButton = self.tabBar.subviews.last, let tabItemImageView = lastTabBarButton.subviews.first {
            if let accountTabBarItem = self.tabBar.items?.last {
                accountTabBarItem.selectedImage = nil
                accountTabBarItem.image = nil
            }
            let imgView = UIImageView()
            imgView.frame = tabItemImageView.frame
            imgView.layer.cornerRadius = tabItemImageView.frame.height/2
            imgView.layer.masksToBounds = true
            imgView.contentMode = .scaleAspectFill
            imgView.clipsToBounds = true
            imgView.image = UIImage(named: imageName)
            self.tabBar.subviews.last?.addSubview(imgView)
        }
    }
}

现在打开 ViewController.swift 文件添加以下方法:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.tabBarController?.addSubviewToLastTabItem("profile")
}

Reference Guide

关于ios - 在 Swift 中以编程方式设置时配置文件选项卡栏图像像素化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56184472/

相关文章:

ios - 在 Swift 中创建类和结构来表示 JSON 对象

ios - Swift NSMutableDictionary 删除对象

ios - 查询 Firebase 以查找值的每个实例

swift - 使用 Xcode/Swift,如何使用 SF Symbol 作为 Assets 中的标签栏图标? asset 字段不接受 .svg 文件

iphone - 如何在 Tabbar Controller 之前显示登录 View ?

objective-c - ios int 到 float 比较总是计算为 true

ios - 如何使用具有正确布局测量值的 iOSDropDown Pod 创建下拉菜单

ios - 如何优化过滤器性能 CIFilter

iOS:是否可以通过蓝牙将字符串发送到计算机,只需给它 MAC 地址

swift - 如何在 tvos 中的 TabBar 项目上全屏播放视频