it-swarm.com.ru

как заставить изображение индикатора выбора UITabBar заполнить все пространство?

У меня есть UITabBarController, где я использую этот код для установки изображения индикатора выбора:

let selectedBG = UIImage(named:"tabbarbgtest.png")?.resizableImageWithCapInsets(UIEdgeInsetsMake(0, 0, 0, 0))
UITabBar.appearance().selectionIndicatorImage = selectedBG

Но изображение не заполняет все пространство - см. Изображение ниже:

 enter image description here

Изображение представляет собой просто красный квадрат с разрешением 82x49px, но с более широким изображением оно все еще не заполняет все пространство. Надеюсь, вы, ребята, можете помочь - спасибо.

11
Loc Dai Le

Если вы хотите установить красное изображение на вкладке, я рекомендую вам установить цвет фона для активного элемента панели вкладок, на мой взгляд, всякий раз, когда вы можете делать свои вещи с кодировкой, зачем использовать изображение, так что лучше выбрать цвет выделения, чем image . Вы можете добиться этого, используя следующий код. 

    // set red as selected background color
    let numberOfItems = CGFloat(tabBar.items!.count)
    let tabBarItemSize = CGSize(width: tabBar.frame.width / numberOfItems, height: tabBar.frame.height)
    tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.red, size: tabBarItemSize).resizableImage(withCapInsets: .zero)

    // remove default border
    tabBar.frame.size.width = self.view.frame.width + 4
    tabBar.frame.Origin.x = -2

Использование следующего расширения UIImage:

extension UIImage {
    class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
        let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

Надеюсь, что это поможет вам.

ИЛИДРУГОЙ ПУТЬ IS ЗДЕСЬ:

В вашем tabBarController вы можете установить UITabBar tintColor по умолчанию, barTintColor, selectionIndicatorImage (немного читерский здесь) и режим отображения изображений, см. Комментарии ниже:

    class MyTabBarController: UITabBarController, UINavigationControllerDelegate {
    ...
    override func viewDidLoad() {
        ...
            // Sets the default color of the icon of the selected UITabBarItem and Title
            UITabBar.appearance().tintColor = UIColor.red
        // Sets the default color of the background of the UITabBar
        UITabBar.appearance().barTintColor = UIColor.black

        // Sets the background color of the selected UITabBarItem (using and plain colored UIImage with the width = 1/5 of the tabBar (if you have 5 items) and the height of the tabBar)
        UITabBar.appearance().selectionIndicatorImage = UIImage().makeImageWithColorAndSize(color: UIColor.blue, size: CGSize(width: tabBar.frame.width/5, height: tabBar.frame.height))

        // Uses the original colors for your images, so they aren't not rendered as grey automatically.
        for item in (self.tabBar.items)! {
        if let image = item.image {
            item.image = image.withRenderingMode(.alwaysOriginal)
        }
    }
    }
    ...
}

И вы захотите расширить класс UIImage, чтобы сделать одноцветное изображение нужного размера:

 extension UIImage {
    func makeImageWithColorAndSize(color: UIColor, size: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}
29
Piyush Patel

По состоянию на 2017 год, честно говоря, ответ Пиюша не работал для меня. После нескольких дней поиска другого решения я нашел свое - by subclassing the UITabBarController.

Он работает для нескольких устройств даже с вращением.

Заметки :

  1. Сделайте режим рендеринга ваших изображений как Original.
  2. Присвойте этот класс ниже вашему UITabBarController в вашей раскадровке или как базовый класс, если вы делаете экран программно.

    //
    //  BaseTabBarController.Swift
    //  MyApp
    //
    //  Created by DRC on 1/27/17.
    //  Copyright © 2017 PrettyITGirl. All rights reserved.
    //
    
    import UIKit
    
    class BaseTabBarController: UITabBarController {
    
        let numberOfTabs: CGFloat = 4
        let tabBarHeight: CGFloat = 60
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            updateSelectionIndicatorImage()
        }
    
        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            updateSelectionIndicatorImage()
        }
    
        func updateSelectionIndicatorImage() {
            let width = tabBar.bounds.width
            var selectionImage = UIImage(named:"myimage.png")
            let tabSize = CGSize(width: width/numberOfTabs, height: tabBarHeight)
    
            UIGraphicsBeginImageContext(tabSize)
            selectionImage?.draw(in: CGRect(x: 0, y: 0, width: tabSize.width, height: tabSize.height))
            selectionImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            tabBar.selectionIndicatorImage = selectionImage
        }
    
    }
    
8
Glenn

Для поддержки iPhone X (приведенный ниже код работает для всех версий), напишите свой код в viewDidLayoutSubviews ().

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let tabWidth = (tabBar.frame.width/CGFloat(tabBar.items!.count))
    let tabHeight = tabBar.frame.height
    self.tabBar.selectionIndicatorImage = imageWithColor(color: UIColor.white, size: CGSize(width: tabWidth, height: tabHeight)).resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
 }

Источник: https://github.com/Ramotion/animated-tab-bar/issues/191

1
Suresh Durishetti

вы должны взглянуть на this , чтобы изменить размер tabbarbgtest.png, затем назначить изображение для selectionIndicatorImage, вы даже можете сделать это в редакторе раскадровки.

1
Allen

Это относительно простое решение в Objective C работало для меня на iPhone X, его было бы нетрудно преобразовать в Swift:

CGFloat bottomPadding = 0;

if (@available(iOS 11.0, *)) {
  UIWindow *window = UIApplication.sharedApplication.keyWindow;
  bottomPadding = window.safeAreaInsets.bottom;
}

[UITabBar.appearance setSelectionIndicatorImage:[UIImage imageWithColor:[UIColor lightGrayColor] 
          andBounds:CGRectMake(0, 0, self.tabBar.frame.size.width/5, self.tabBar.frame.size.height + bottomPadding)]];
0
joshwithguitar

Это адаптация к решению Гленна выше ...

    import UIKit

    class BaseTabBarController: UITabBarController {

        var tabBarBounds: CGRect? {
            didSet {
                guard tabBarBounds != oldValue else { return }
                updateSelectionIndicatorColor(UIColor.green)
            }
        }

        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
            tabBarBounds = tabBar.bounds
        }

        func updateSelectionIndicatorColor(_ tintColor: UIColor) {
            guard let tabBarItems = self.tabBar.items else { return }

            let tabWidth = tabBar.bounds.width
            let tabHeight = tabBar.bounds.height
            let tabSize = CGSize(width: tabWidth / CGFloat(tabBarItems.count), height: tabHeight)
            var selectionImage = UIImage(color: tintColor, size: tabSize)

            UIGraphicsBeginImageContext(tabSize)
            selectionImage?.draw(in: CGRect(x: 0, y: 0, width: tabSize.width, height: tabSize.height))
            selectionImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            tabBar.selectionIndicatorImage = selectionImage
        }

    }

    public extension UIImage {
        public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
            let rect = CGRect(Origin: .zero, size: size)
            UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
            color.setFill()
            UIRectFill(rect)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            guard let cgImage = image?.cgImage else { return nil }
            self.init(cgImage: cgImage)
        }
    }
0
Marsh