Ios 如何纠正iPhone X上的选项卡栏高度问题
在测试iPhoneX时,我的应用程序出现问题。我不确定如何调整这个问题,也不确定如何使它成为非iPhoneX尺寸的问题。这似乎只是iPhoneX模拟器上的一个问题Ios 如何纠正iPhone X上的选项卡栏高度问题,ios,swift,xcode,uistoryboard,iphone-x,Ios,Swift,Xcode,Uistoryboard,Iphone X,在测试iPhoneX时,我的应用程序出现问题。我不确定如何调整这个问题,也不确定如何使它成为非iPhoneX尺寸的问题。这似乎只是iPhoneX模拟器上的一个问题 视图中UITabBar的invalidateIntrinsicContentSize将布局子视图,这可能会对您有所帮助 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() self.tabBar.invalidateIntr
视图中UITabBar的invalidateIntrinsicContentSize将布局子视图,这可能会对您有所帮助
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.tabBar.invalidateIntrinsicContentSize()
}
“文件检查器”位于Xcode情节提要的右侧,启用安全区域指南布局以支持iPhone中的应用程序
非常好地描述了它。在约束中-
如果您使用“底部布局指南”提供底部空间,则会出现此问题
解决方案:
为superview提供底部空间。这将100%完美地工作。我的解决方案是,我有一个自定义的UITabBar高度设置,如下所示:
override func viewWillLayoutSubviews() {
var tabFrame = tabBar.frame
tabFrame.size.height = 60
tabFrame.origin.y = self.view.frame.size.height - 60
tabBar.frame = tabFrame
}
移除它,选项卡栏将在iPhone X上正确显示。这对我来说很有效,因为我正在使用选择图像
tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.NewDesignColor.yellow, size: tabBarItemSize).resizableImage(withCapInsets: UIEdgeInsets.init(top: 0, left: 0, bottom: 20, right: 0))
在我的例子中,添加底部插图很有帮助。
希望这对你的工作以及。
谢谢。对于iOS 11.3,这对我很有用:
func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tabBar.invalidateIntrinsicContentSize()
}
我也有类似的问题。我正在viewDidLoad()中设置selectionIndicatorImage。将代码移动到viewDidLayoutSubviews()修复了我的问题。使用以下代码创建一个单独的文件:
extension UITabBar {
override open func sizeThatFits(_ size: CGSize) -> CGSize {
super.sizeThatFits(size)
guard let window = UIApplication.shared.keyWindow else {
return super.sizeThatFits(size)
}
var sizeThatFits = super.sizeThatFits(size)
sizeThatFits.height = window.safeAreaInsets.bottom + 40
return sizeThatFits
}
}
只需将UITabBar的底部与superview对齐,而不是与安全区域对齐。如果将其与安全区域对齐,则如下所示:
override func viewWillLayoutSubviews() {
var tabFrame = tabBar.frame
tabFrame.size.height = 60
tabFrame.origin.y = self.view.frame.size.height - 60
tabBar.frame = tabFrame
}
当与superview对齐时,它将正确显示:
我认为这是因为苹果在iPhone X上给了标签栏项目一个默认的底部边距,因为他们希望标签栏延伸到屏幕底部,以避免浮动条。请遵循以下设置UITabbar selectionIndicatorImage的指导原则
tabbar selectionIndicatorImage的默认高度为49,但在iPhone X中,将图像高度设置为48。在iOS 12.1上我通过覆盖UITabBar子类中的safeAreaInsets解决了这个问题:
class TabBar: UITabBar {
private var cachedSafeAreaInsets = UIEdgeInsets.zero
override var safeAreaInsets: UIEdgeInsets {
let insets = super.safeAreaInsets
if insets.bottom < bounds.height {
cachedSafeAreaInsets = insets
}
return cachedSafeAreaInsets
}
}
class选项卡栏:uitabar{
private var cachedSafeAreaInsets=UIEdgeInsets.zero
覆盖var安全区域插图:UIEdgeInsets{
let insets=超级安全区域insets
如果insets.bottom
对于iOS 13.0以后的版本,
class TabBar: UITabBar {
private var cachedSafeAreaInsets = UIEdgeInsets.zero
let keyWindow = UIApplication.shared.connectedScenes
.filter { $0.activationState == .foregroundActive }
.compactMap { $0 as? UIWindowScene }
.first?.windows
.filter { $0.isKeyWindow }
.first
override var safeAreaInsets: UIEdgeInsets {
if let insets = keyWindow?.safeAreaInsets {
if insets.bottom < bounds.height {
cachedSafeAreaInsets = insets
}
}
return cachedSafeAreaInsets
}
}
class选项卡栏:uitabar{
private var cachedSafeAreaInsets=UIEdgeInsets.zero
让keyWindow=UIApplication.shared.connectedScenes
.filter{$0.activationState==.foregroundActive}
.compactMap{$0作为?UIWindowScene}
.第一个?.窗户
.filter{$0.isKeyWindow}
.首先
覆盖var安全区域插图:UIEdgeInsets{
如果let insets=keyWindow?.safeAreaInsets{
如果insets.bottom
有一个uitabar
子类解决了我在iphonexios11上的所有问题
class TabBar: UITabBar {
private var _safeAreaInsets = UIEdgeInsets.zero
private var _subviewsFrames: [CGRect] = []
@available(iOS 11.0, *)
override func safeAreaInsetsDidChange() {
super.safeAreaInsetsDidChange()
if _safeAreaInsets != safeAreaInsets {
_safeAreaInsets = safeAreaInsets
invalidateIntrinsicContentSize()
superview?.setNeedsLayout()
superview?.layoutSubviews()
}
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
var size = super.sizeThatFits(size)
if #available(iOS 12.0, *) {
let bottomInset = safeAreaInsets.bottom
if bottomInset > 0 && size.height < 50 && (size.height + bottomInset < 90) {
size.height += bottomInset
}
}
return size
}
override var frame: CGRect {
get {
return super.frame
}
set {
var tmp = newValue
if let superview = superview, tmp.maxY !=
superview.frame.height {
tmp.origin.y = superview.frame.height - tmp.height
}
super.frame = tmp
}
}
override func layoutSubviews() {
super.layoutSubviews()
let state = subviews.map { $0.frame }
if (state.first { $0.width == 0 } == nil) {
_subviewsFrames = state
} else {
zip(subviews, _subviewsFrames).forEach { (view, rect) in
view.frame = rect
}
}
}
}
class选项卡栏:uitabar{
私有变量_safeAreaInsets=UIEdgeInsets.zero
私有变量\u子视图框架:[CGRect]=[]
@可用(iOS 11.0,*)
重写函数safeAreaInsetsDidChange(){
super.safeareainsertsdidchange()
如果_safeAreaInsets!=safeAreaInsets{
_安全区域插图=安全区域插图
InvalidateIntriseContentSize()无效
superview?.setNeedsLayout()
superview?.layoutSubviews()
}
}
重写func sizeThatFits(usize:CGSize)->CGSize{
var size=super.sizeThatFits(大小)
如果可用(iOS 12.0,*){
让bottomInset=安全区域inset.bottom
如果底部插图>0&&size.height<50&&size.height+底部插图<90){
尺寸.高度+=底部插图
}
}
返回大小
}
覆盖变量帧:CGRect{
得到{
返回超级帧
}
设置{
var tmp=新值
如果让superview=superview,则tmp.maxY=
superview.frame.height{
tmp.origin.y=superview.frame.height-tmp.height
}
super.frame=tmp
}
}
覆盖func布局子视图(){
super.layoutSubviews()
让state=subviews.map{$0.frame}
如果(state.first{$0.width==0}==nil){
_子视图框架=状态
}否则{
zip(子视图,_子视图框架).forEach{(视图,rect)in
view.frame=rect
}
}
}
}
苹果现在已经在iOS 12.1.1中解决了这个问题看起来很疯狂,但我只需要删除代码中的这一行
self.view.layoutIfNeeded()
我只是猜测,在屏幕上没有显示的视图上需要调用layoutifn会导致这个问题发生。
无论如何,@mohamed ali的解决方案也能正常工作。非常感谢。在viewDidLoad中添加此代码
DispatchQueue.main.async {
let size = CGSize(width: self.tabBar.frame.width / numberOfTabsFloat,
height: self.tabBar.frame.height)
let image = UIImage.drawTabBarIndicator(color: UIColor.white,
size: size,
onTop: false)
UITabBar.appearance().selectionIndicatorImage = image
self.tabBar.selectionIndicatorImage = image
}
并添加此扩展名
extension UIImage{
//Draws the top indicator by making image with filling color
class func drawTabBarIndicator(color: UIColor, size: CGSize, onTop: Bool) -> UIImage {
let indicatorHeight = size.height
let yPosition = onTop ? 0 : (size.height - indicatorHeight)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(CGRect(x: 0, y: yPosition, width: size.width, height: indicatorHeight))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
如果UIViewController是可旋转的,则将其放入UIAbbarViewController以更正选项卡栏高度
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
tabBar.sizeToFit()
}
这对我有用
[self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.layoutMarginsGuide.bottomAnchor].active = YES;
我只在iOS 11.0以上和12.0以下遇到了这个表面问题
我从UITabBar继承了一个CustomTabBar类。
我覆盖框架方法,如下所示:
- (CGRect)frame{
return self.bounds;
}
虽然我的答案晚了,但我可以向您保证,如果您在iphone x、xs或max屏幕上遇到类似的问题,请确保您上传的图像大小必须为height=width*48pxHeight,对我有效的方法是向viewDidLoad添加以下行:
[self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
约拿和梅胡尔·塔卡尔的回答为我指明了正确的方向
注意:我在情节提要中只有一个空白的选项卡栏控制器。选项卡栏“图像和视图控制”