在Swift上以编程方式设置时,配置文件标签栏图像像素化

时间:2019-05-17 10:23:38

标签: 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对象的方法,但未发现任何结果。

关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:0)

在项目中添加以下扩展名,您可以在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