自定义 UItababbar swift
Customising UItababbar swift
任何人都可以告诉我如何在 UITabbar 中实现这样的设计。我试过添加背景图像,但这看起来不像设计。这里的曲线超出了 UITabbar 的框架,不知道如何将这个视图添加到活动标签栏的顶部。
将原生 UITabBar 的外观优雅地更改到那种程度是不可能的。您的选择是创建一个像 UITabBarController 一样的自定义容器视图控制器,或者只是隐藏默认选项卡栏并在 space.
中实现您自己的视图
尽管它不太优雅,因为您只是在默认选项卡栏上放置一个视图,但我实际上喜欢这种方法,因为您保留了本机 UITabBarController 的优点(调用 self.tabBarController?它的视图控制器,它已经调整了布局边距等)。
为此,在 UITabBarController 的子类中隐藏 tabBar:
self.tabBar.isHidden = true
self.tabBar.alpha = 0
然后在根据需要实现自定义视图后,只需在 viewDidLayoutSubviews 中将自定义视图的框架设置为 self.tabBar.frame。
要更改视图控制器,请在用户点击您的自定义选项卡之一时调用它:
self.selectedIndex = newIndex
从UITabBarController
创建自定义TabBar可以解决问题。不要将直接图像添加到 Tabbar,而是使用动态图像使用 UIGraphicsBeginImageContext
for selectedTabBackgroundImage
。
- 创建图像。
- 剪掉图片中的圆形顶部
这是代码示例。
import UIKit
class CustomTabBarViewController: UITabBarController {
var topClipSize: CGFloat = 24.5 //Adjust based on the number of tabbar
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let singleTabWidth: CGFloat = self.tabBar.frame.size.width / CGFloat((self.tabBar.items?.count)!)
let singleTabSize = CGSize(width:singleTabWidth , height: self.tabBar.frame.size.height)
// Create the backgound image
let selectedTabBackgroundImage: UIImage = self.imageWithColor(color: .blue, size: singleTabSize)
// Clip the top
self.tabBar.selectionIndicatorImage = selectedTabBackgroundImage.roundTopImage(topClipSize: topClipSize)
}
func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
if size.height > 55 {
topClipSize = 30.0 // iPhone 8 tabbar height is 53 and iPnone X is 83 - We need more space on top.
}
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height + topClipSize)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
extension UIImage {
func roundTopImage(topClipSize: CGFloat) -> UIImage {
let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size)
let rectBounds: CGRect = CGRect(x: rect.origin.x, y: rect.origin.y + (topClipSize * 2), width: rect.size.width, height: rect.size.height - (topClipSize * 2))
let ovalBounds: CGRect = CGRect(x: rect.origin.x - topClipSize, y: rect.origin.y, width: rect.size.width + (topClipSize * 2), height: rect.size.height)
UIGraphicsBeginImageContextWithOptions(self.size, false, 1)
let rectPath = UIBezierPath(rect: rectBounds)
let ovalPath = UIBezierPath(ovalIn: ovalBounds)
rectPath.append(ovalPath)
rectPath.addClip()
self.draw(in: rect)
return UIGraphicsGetImageFromCurrentImageContext()!
}
}
这是输出:
任何人都可以告诉我如何在 UITabbar 中实现这样的设计。我试过添加背景图像,但这看起来不像设计。这里的曲线超出了 UITabbar 的框架,不知道如何将这个视图添加到活动标签栏的顶部。
将原生 UITabBar 的外观优雅地更改到那种程度是不可能的。您的选择是创建一个像 UITabBarController 一样的自定义容器视图控制器,或者只是隐藏默认选项卡栏并在 space.
中实现您自己的视图尽管它不太优雅,因为您只是在默认选项卡栏上放置一个视图,但我实际上喜欢这种方法,因为您保留了本机 UITabBarController 的优点(调用 self.tabBarController?它的视图控制器,它已经调整了布局边距等)。
为此,在 UITabBarController 的子类中隐藏 tabBar:
self.tabBar.isHidden = true
self.tabBar.alpha = 0
然后在根据需要实现自定义视图后,只需在 viewDidLayoutSubviews 中将自定义视图的框架设置为 self.tabBar.frame。
要更改视图控制器,请在用户点击您的自定义选项卡之一时调用它:
self.selectedIndex = newIndex
从UITabBarController
创建自定义TabBar可以解决问题。不要将直接图像添加到 Tabbar,而是使用动态图像使用 UIGraphicsBeginImageContext
for selectedTabBackgroundImage
。
- 创建图像。
- 剪掉图片中的圆形顶部
这是代码示例。
import UIKit
class CustomTabBarViewController: UITabBarController {
var topClipSize: CGFloat = 24.5 //Adjust based on the number of tabbar
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let singleTabWidth: CGFloat = self.tabBar.frame.size.width / CGFloat((self.tabBar.items?.count)!)
let singleTabSize = CGSize(width:singleTabWidth , height: self.tabBar.frame.size.height)
// Create the backgound image
let selectedTabBackgroundImage: UIImage = self.imageWithColor(color: .blue, size: singleTabSize)
// Clip the top
self.tabBar.selectionIndicatorImage = selectedTabBackgroundImage.roundTopImage(topClipSize: topClipSize)
}
func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
if size.height > 55 {
topClipSize = 30.0 // iPhone 8 tabbar height is 53 and iPnone X is 83 - We need more space on top.
}
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height + topClipSize)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context!.setFillColor(color.cgColor)
context!.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
extension UIImage {
func roundTopImage(topClipSize: CGFloat) -> UIImage {
let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.size)
let rectBounds: CGRect = CGRect(x: rect.origin.x, y: rect.origin.y + (topClipSize * 2), width: rect.size.width, height: rect.size.height - (topClipSize * 2))
let ovalBounds: CGRect = CGRect(x: rect.origin.x - topClipSize, y: rect.origin.y, width: rect.size.width + (topClipSize * 2), height: rect.size.height)
UIGraphicsBeginImageContextWithOptions(self.size, false, 1)
let rectPath = UIBezierPath(rect: rectBounds)
let ovalPath = UIBezierPath(ovalIn: ovalBounds)
rectPath.append(ovalPath)
rectPath.addClip()
self.draw(in: rect)
return UIGraphicsGetImageFromCurrentImageContext()!
}
}
这是输出: