我想创建一个简单的 mobilesubstrate tweak ,隐藏并显示状态栏图标,如电池或运营商或wifi信号打字机。我已经看过libstatusbar项目,但我无法找到隐藏iOS图标的方法。没有使用这个库,有没有其他方法可以做到这一点?我只是想隐藏并显示默认图标
答案 0 :(得分:4)
使用公共API无法实现。您只能隐藏整个状态栏,而不仅仅是它的某些元素。
对于越狱,请看一下:
https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIStatusBarItem.h
特别是,请看以下方法:
+ (BOOL)itemType:(int)arg1 idiom:(int)arg2 appearsInRegion:(int)arg3;
+ (BOOL)itemType:(int)arg1 idiom:(int)arg2 canBeEnabledForData:(id)arg3 style:(id)arg4;
无论是否出现这些方法,都要咨询这些方法。在此处返回NO
以禁用项目。
答案 1 :(得分:2)
以下是我在调整中使用的内容:
int itemToHide = 0;
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] beginCoalescentBlock];
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] _setItem:itemToHide enabled:NO];
[[objc_getClass("SBStatusBarStateAggregator") sharedInstance] endCoalescentBlock];
唯一的问题 - iOS使用状态栏项的整数值,并且它们在不同的iOS版本上有所不同。您可以测试每个iOS版本并为每个版本存储值,但我找到了更好的方法。
我挂钩SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2
方法。然后我调用其中一个SBStatusBarStateAggregator -(void)_update****
方法。例如,让我们说我想找到位置图标索引。我叫SBStatusBarStateAggregator -(void)_updateLocationItem
方法。然后它将调用hooked SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2
,我将存储索引。
我也挂钩SBStatusBarStateAggregator -(void)_notifyItemChanged:(int)arg
。此方法作为SBStatusBarStateAggregator -(void)_update****
调用的一部分进行调用。在确定状态栏图标索引时,我只需通过返回而不调用原始实现来忽略对它的调用。
如果你想永久隐藏一些图标,你仍需要挂钩SBStatusBarStateAggregator _setItem:(int)arg1 enabled:(BOOL)arg2
和SBStatusBarStateAggregator -(void)_notifyItemChanged:(int)arg
,以便忽略任何iOS尝试显示隐藏的图标。例如,信号电平和数据/时间在每次更新时都会重新启用。
这完全适用于iOS 7.在iOS 5-6 API上有所不同,但我使用的方法几乎相同。隐藏状态栏项目
int itemToHide = 0;
[[objc_getClass("SBStatusBarDataManager") sharedDataManager] setStatusBarItem:itemToHide enabled:NO];
我挂钩SBStatusBarDataManager -(void)updateStatusBarItem:(int)item
以确定图标索引,然后在位置图标的情况下调用SBStatusBarDataManager -(void)_locationStatusChange
。
答案 2 :(得分:1)
确定。这是解决方案 在plist文件中添加行:
View controller-based status bar appearance : NO
使用此内容在UINavigationBar上创建一个类别:
#import "UINavigationBar+StatusBar.h" #import @implementation UINavigationBar (StatusBar) + (void)load { [self swizzleOriginalSelectorWithName:@"layoutSubviews" toSelectorWithName:@"my_layoutSubviews"]; } - (void)my_layoutSubviews { [self my_layoutSubviews]; [self setFrame:CGRectMake(0, 0, self.frame.size.width, 64)]; } + (void)swizzleOriginalSelectorWithName:(NSString *)origName toSelectorWithName:(NSString *)swizzleName { Method origMethod = class_getInstanceMethod([self class], NSSelectorFromString(origName)); Method newMethod = class_getInstanceMethod([self class], NSSelectorFromString(swizzleName)); method_exchangeImplementations(origMethod, newMethod); } @end
这会增加20pt的导航栏。
然后,为状态栏创建自定义视图。 e.g。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self makeCustomSatusBar]; // Override point for customization after application launch. return YES; } - (void)makeCustomSatusBar { [[UIApplication sharedApplication] setStatusBarHidden:YES]; UIColor *statusBarColor = [UIColor blackColor]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.frame.size.width, 20)]; view.layer.zPosition = INT_MAX; view.backgroundColor = [UIColor clearColor]; // Making time label NSDateFormatter *formatter = [NSDateFormatter new]; formatter.dateFormat = @"HH:mm"; UILabel *timeLabel = [UILabel new]; timeLabel.text = [formatter stringFromDate:[NSDate date]]; timeLabel.textColor = statusBarColor; timeLabel.font = [UIFont systemFontOfSize:12]; [timeLabel sizeToFit]; timeLabel.center = CGPointMake(view.frame.size.width/2, view.frame.size.height/2); [view addSubview:timeLabel]; // // make other indicators you need... //... [self.window addSubview:view]; }
你会有这样的事情:
请注意,您需要每次更新自定义视图的值(即时间标签,电池等等),因此最好为状态栏创建一个单独的类,并使用无限制的计时器1秒钟打勾并在计时器的操作中进行更新。
答案 3 :(得分:0)
[[UIApplication sharedApplication] setStatusBarHidden:YES]
如果您想在20pt高度之上只有空视图,那么将其添加到UIWindow,并将UIWindow的子视图向下移动20 pt