mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
432 lines
17 KiB
Objective-C
432 lines
17 KiB
Objective-C
#import "UINavigationItem+Proxy.h"
|
|
|
|
#import "NSBag.h"
|
|
#import <ObjCRuntimeUtils/RuntimeUtils.h>
|
|
#import "NSWeakReference.h"
|
|
|
|
static const void *sourceItemKey = &sourceItemKey;
|
|
static const void *targetItemKey = &targetItemKey;
|
|
static const void *setTitleListenerBagKey = &setTitleListenerBagKey;
|
|
static const void *setImageListenerBagKey = &setImageListenerBagKey;
|
|
static const void *setSelectedImageListenerBagKey = &setSelectedImageListenerBagKey;
|
|
static const void *setTitleViewListenerBagKey = &setTitleViewListenerBagKey;
|
|
static const void *setLeftBarButtonItemListenerBagKey = &setLeftBarButtonItemListenerBagKey;
|
|
static const void *setRightBarButtonItemListenerBagKey = &setRightBarButtonItemListenerBagKey;
|
|
static const void *setMultipleRightBarButtonItemsListenerKey = &setMultipleRightBarButtonItemsListenerKey;
|
|
static const void *setBackBarButtonItemListenerBagKey = &setBackBarButtonItemListenerBagKey;
|
|
static const void *setBadgeListenerBagKey = &setBadgeListenerBagKey;
|
|
static const void *badgeKey = &badgeKey;
|
|
static const void *animationNameKey = &animationNameKey;
|
|
static const void *animationOffsetKey = &animationOffsetKey;
|
|
static const void *ringSelectionKey = &ringSelectionKey;
|
|
|
|
@implementation UINavigationItem (Proxy)
|
|
|
|
+ (void)load
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setTitle:) newSelector:@selector(_ac91f40f_setTitle:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setTitleView:) newSelector:@selector(_ac91f40f_setTitleView:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setLeftBarButtonItem:) newSelector:@selector(_ac91f40f_setLeftBarButtonItem:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setLeftBarButtonItem:animated:) newSelector:@selector(_ac91f40f_setLeftBarButtonItem:animated:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItem:) newSelector:@selector(_ac91f40f_setRightBarButtonItem:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItem:animated:) newSelector:@selector(_ac91f40f_setRightBarButtonItem:animated:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItems:) newSelector:@selector(_ac91f40f_setRightBarButtonItems:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setRightBarButtonItems:animated:) newSelector:@selector(_ac91f40f_setRightBarButtonItems:animated:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UINavigationItem class] currentSelector:@selector(setBackBarButtonItem:) newSelector:@selector(_ac91f40f_setBackBarButtonItem:)];
|
|
});
|
|
}
|
|
|
|
- (void)_ac91f40f_setTitle:(NSString *)title
|
|
{
|
|
[self _ac91f40f_setTitle:title];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setTitle:title];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setTitleListenerBagKey] enumerateItems:^(UINavigationItemSetTitleListener listener) {
|
|
listener(title, false);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)setTitle:(NSString * _Nullable)title animated:(bool)animated {
|
|
[self _ac91f40f_setTitle:title];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setTitle:title];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setTitleListenerBagKey] enumerateItems:^(UINavigationItemSetTitleListener listener) {
|
|
listener(title, animated);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_ac91f40f_setTitleView:(UIView *)titleView
|
|
{
|
|
[self _ac91f40f_setTitleView:titleView];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setTitleView:titleView];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setTitleViewListenerBagKey] enumerateItems:^(UINavigationItemSetTitleViewListener listener) {
|
|
listener(titleView);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_ac91f40f_setLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem {
|
|
[self setLeftBarButtonItem:leftBarButtonItem animated:false];
|
|
}
|
|
|
|
- (void)_ac91f40f_setLeftBarButtonItem:(UIBarButtonItem *)leftBarButtonItem animated:(BOOL)animated
|
|
{
|
|
UIBarButtonItem *previousItem = self.leftBarButtonItem;
|
|
|
|
[self _ac91f40f_setLeftBarButtonItem:leftBarButtonItem animated:animated];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setLeftBarButtonItem:leftBarButtonItem animated:animated];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setLeftBarButtonItemListenerBagKey] enumerateItems:^(UINavigationItemSetBarButtonItemListener listener) {
|
|
listener(previousItem, leftBarButtonItem, animated);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_ac91f40f_setRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem {
|
|
[self setRightBarButtonItem:rightBarButtonItem animated:false];
|
|
}
|
|
|
|
- (void)_ac91f40f_setRightBarButtonItem:(UIBarButtonItem *)rightBarButtonItem animated:(BOOL)animated
|
|
{
|
|
UIBarButtonItem *previousItem = self.rightBarButtonItem;
|
|
|
|
[self _ac91f40f_setRightBarButtonItem:rightBarButtonItem animated:animated];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setRightBarButtonItem:rightBarButtonItem animated:animated];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setRightBarButtonItemListenerBagKey] enumerateItems:^(UINavigationItemSetBarButtonItemListener listener) {
|
|
listener(previousItem, rightBarButtonItem, animated);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_ac91f40f_setRightBarButtonItems:(NSArray<UIBarButtonItem *> *)rightBarButtonItems {
|
|
[self setRightBarButtonItems:rightBarButtonItems animated:false];
|
|
}
|
|
|
|
- (void)_ac91f40f_setRightBarButtonItems:(NSArray<UIBarButtonItem *> *)rightBarButtonItems animated:(BOOL)animated
|
|
{
|
|
[self _ac91f40f_setRightBarButtonItems:rightBarButtonItems animated:animated];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setRightBarButtonItems:rightBarButtonItems animated:animated];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey] enumerateItems:^(UINavigationItemSetMutipleBarButtonItemsListener listener) {
|
|
listener(rightBarButtonItems, animated);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)_ac91f40f_setBackBarButtonItem:(UIBarButtonItem *)backBarButtonItem
|
|
{
|
|
UIBarButtonItem *previousItem = self.backBarButtonItem;
|
|
|
|
[self _ac91f40f_setBackBarButtonItem:backBarButtonItem];
|
|
|
|
UINavigationItem *targetItem = [self associatedObjectForKey:targetItemKey];
|
|
if (targetItem != nil) {
|
|
[targetItem setBackBarButtonItem:backBarButtonItem];
|
|
} else {
|
|
[(NSBag *)[self associatedObjectForKey:setBackBarButtonItemListenerBagKey] enumerateItems:^(UINavigationItemSetBarButtonItemListener listener) {
|
|
listener(previousItem, backBarButtonItem, false);
|
|
}];
|
|
}
|
|
}
|
|
|
|
- (void)setTargetItem:(UINavigationItem *)targetItem {
|
|
NSWeakReference *previousSourceItem = [targetItem associatedObjectForKey:sourceItemKey];
|
|
[(UINavigationItem *)previousSourceItem.value setAssociatedObject:nil forKey:targetItemKey associationPolicy:NSObjectAssociationPolicyRetain];
|
|
|
|
[self setAssociatedObject:targetItem forKey:targetItemKey associationPolicy:NSObjectAssociationPolicyRetain];
|
|
[targetItem setAssociatedObject:[[NSWeakReference alloc] initWithValue:self] forKey:sourceItemKey associationPolicy:NSObjectAssociationPolicyRetain];
|
|
|
|
if ((targetItem.title != nil) != (self.title != nil) || ![targetItem.title isEqualToString:self.title]) {
|
|
targetItem.title = self.title;
|
|
}
|
|
if (targetItem.titleView != self.titleView) {
|
|
[targetItem setTitleView:self.titleView];
|
|
}
|
|
if (targetItem.leftBarButtonItem != self.leftBarButtonItem) {
|
|
[targetItem setLeftBarButtonItem:self.leftBarButtonItem];
|
|
}
|
|
if (targetItem.rightBarButtonItem != self.rightBarButtonItem) {
|
|
[targetItem setRightBarButtonItem:self.rightBarButtonItem];
|
|
}
|
|
if (targetItem.backBarButtonItem != self.backBarButtonItem) {
|
|
[targetItem setBackBarButtonItem:self.backBarButtonItem];
|
|
}
|
|
}
|
|
|
|
- (BOOL)hasTargetItem {
|
|
return [self associatedObjectForKey:targetItemKey] != nil;
|
|
}
|
|
|
|
- (NSInteger)addSetTitleListener:(UINavigationItemSetTitleListener)listener
|
|
{
|
|
NSBag *bag = [self associatedObjectForKey:setTitleListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setTitleListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetTitleListener:(NSInteger)key
|
|
{
|
|
[(NSBag *)[self associatedObjectForKey:setTitleListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetTitleViewListener:(UINavigationItemSetTitleViewListener)listener
|
|
{
|
|
NSBag *bag = [self associatedObjectForKey:setTitleViewListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setTitleViewListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetTitleViewListener:(NSInteger)key
|
|
{
|
|
[(NSBag *)[self associatedObjectForKey:setTitleViewListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetLeftBarButtonItemListener:(UINavigationItemSetBarButtonItemListener)listener
|
|
{
|
|
NSBag *bag = [self associatedObjectForKey:setLeftBarButtonItemListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setLeftBarButtonItemListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetLeftBarButtonItemListener:(NSInteger)key
|
|
{
|
|
[(NSBag *)[self associatedObjectForKey:setLeftBarButtonItemListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetRightBarButtonItemListener:(UINavigationItemSetBarButtonItemListener)listener
|
|
{
|
|
NSBag *bag = [self associatedObjectForKey:setRightBarButtonItemListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setRightBarButtonItemListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetRightBarButtonItemListener:(NSInteger)key
|
|
{
|
|
[(NSBag *)[self associatedObjectForKey:setRightBarButtonItemListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetMultipleRightBarButtonItemsListener:(UINavigationItemSetMutipleBarButtonItemsListener _Nonnull)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setMultipleRightBarButtonItemsListenerKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetMultipleRightBarButtonItemsListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setMultipleRightBarButtonItemsListenerKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetBackBarButtonItemListener:(UINavigationItemSetBarButtonItemListener)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setBackBarButtonItemListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setBackBarButtonItemListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetBackBarButtonItemListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setBackBarButtonItemListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetBadgeListener:(UITabBarItemSetBadgeListener)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setBadgeListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setBadgeListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetBadgeListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setBadgeListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (void)setBadge:(NSString *)badge {
|
|
[self setAssociatedObject:badge forKey:badgeKey];
|
|
|
|
[(NSBag *)[self associatedObjectForKey:setBadgeListenerBagKey] enumerateItems:^(UITabBarItemSetBadgeListener listener) {
|
|
listener(badge);
|
|
}];
|
|
}
|
|
|
|
- (NSString *)badge {
|
|
return [self associatedObjectForKey:badgeKey];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation UITabBarItem (Proxy)
|
|
|
|
+ (void)load
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^
|
|
{
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UITabBarItem class] currentSelector:@selector(setBadgeValue:) newSelector:@selector(_ac91f40f_setBadgeValue:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UITabBarItem class] currentSelector:@selector(setTitle:) newSelector:@selector(_ac91f40f_setTitle:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UITabBarItem class] currentSelector:@selector(setImage:) newSelector:@selector(_ac91f40f_setImage:)];
|
|
[RuntimeUtils swizzleInstanceMethodOfClass:[UITabBarItem class] currentSelector:@selector(setSelectedImage:) newSelector:@selector(_ac91f40f_setSelectedImage:)];
|
|
});
|
|
}
|
|
|
|
NSInteger UITabBarItem_addSetBadgeListener(UITabBarItem *item, UITabBarItemSetBadgeListener listener) {
|
|
NSBag *bag = [item associatedObjectForKey:setBadgeListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[item setAssociatedObject:bag forKey:setBadgeListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetBadgeListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setBadgeListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (void)_ac91f40f_setBadgeValue:(NSString *)value {
|
|
[self _ac91f40f_setBadgeValue:value];
|
|
|
|
[(NSBag *)[self associatedObjectForKey:setBadgeListenerBagKey] enumerateItems:^(UITabBarItemSetBadgeListener listener) {
|
|
listener(value);
|
|
}];
|
|
}
|
|
|
|
- (void)_ac91f40f_setTitle:(NSString *)value {
|
|
[self _ac91f40f_setTitle:value];
|
|
|
|
[(NSBag *)[self associatedObjectForKey:setTitleListenerBagKey] enumerateItems:^(UINavigationItemSetTitleListener listener) {
|
|
listener(value, false);
|
|
}];
|
|
}
|
|
|
|
- (void)_ac91f40f_setImage:(UIImage *)value {
|
|
[self _ac91f40f_setImage:value];
|
|
|
|
[(NSBag *)[self associatedObjectForKey:setImageListenerBagKey] enumerateItems:^(UINavigationItemSetImageListener listener) {
|
|
listener(value);
|
|
}];
|
|
}
|
|
|
|
- (void)_ac91f40f_setSelectedImage:(UIImage *)value {
|
|
[self _ac91f40f_setSelectedImage:value];
|
|
|
|
[(NSBag *)[self associatedObjectForKey:setSelectedImageListenerBagKey] enumerateItems:^(UINavigationItemSetImageListener listener) {
|
|
listener(value);
|
|
}];
|
|
}
|
|
|
|
- (NSInteger)addSetTitleListener:(UINavigationItemSetTitleListener)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setTitleListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setTitleListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetTitleListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setTitleListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetImageListener:(UINavigationItemSetImageListener)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setImageListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setImageListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetImageListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setImageListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (NSInteger)addSetSelectedImageListener:(UINavigationItemSetImageListener)listener {
|
|
NSBag *bag = [self associatedObjectForKey:setSelectedImageListenerBagKey];
|
|
if (bag == nil)
|
|
{
|
|
bag = [[NSBag alloc] init];
|
|
[self setAssociatedObject:bag forKey:setSelectedImageListenerBagKey];
|
|
}
|
|
return [bag addItem:[listener copy]];
|
|
}
|
|
|
|
- (void)removeSetSelectedImageListener:(NSInteger)key {
|
|
[(NSBag *)[self associatedObjectForKey:setSelectedImageListenerBagKey] removeItem:key];
|
|
}
|
|
|
|
- (void)setAnimationName:(NSString *)animationName {
|
|
[self setAssociatedObject:animationName forKey:animationNameKey];
|
|
}
|
|
|
|
- (NSString *)animationName {
|
|
return [self associatedObjectForKey:animationNameKey];
|
|
}
|
|
|
|
- (void)setAnimationOffset:(CGPoint)animationOffset {
|
|
[self setAssociatedObject:[NSValue valueWithCGPoint:animationOffset] forKey:animationOffsetKey];
|
|
}
|
|
|
|
- (CGPoint)animationOffset {
|
|
return ((NSValue *)[self associatedObjectForKey:animationOffsetKey]).CGPointValue;
|
|
}
|
|
|
|
- (void)setRingSelection:(bool)ringSelection {
|
|
[self setAssociatedObject:@(ringSelection) forKey:ringSelectionKey];
|
|
}
|
|
|
|
- (bool)ringSelection {
|
|
return ((NSNumber *)[self associatedObjectForKey:ringSelectionKey]).boolValue;
|
|
}
|
|
|
|
@end
|