【问题标题】:How to use UIAppearance to style a subclass but not the superclass?如何使用 UIAppearance 设置子类而不是超类的样式?
【发布时间】:2012-06-13 20:01:57
【问题描述】:

我正在使用UIAppearance 为我的 UINavigationBar 设置样式。我希望所有后退按钮都具有 gray 文本,我的所有 rightBarButtonItems 都具有 green 文本(颜色是假设的)。由于默认情况下这两个按钮都是 UIBarButtonItems,因此 UIAppearance 将无法区分两者。所以我决定继承一个 UIBarButtonItem,称之为 ActionBarButtonItem。我在需要 rightBarButtonItem 的任何地方使用这个新的子类。

rightBarButtonItem

UIBarButtonItem* done = [[ActionBarButtonItem alloc] 
    initWithTitle:@"Done"
    style:UIBarButtonItemStyleDone
    target:self 
    action:@selector(onDonePress)];
self.navigationItem.rightBarButtonItem = done;
[done release];

UI外观

NSDictionary* buttonStyle = [NSDictionary 
    dictionaryWithObjects:[NSArray 
        arrayWithObjects:
            [UIColor grayColor],
            , nil
        ]
        forKeys:[NSArray
            arrayWithObjects:
                UITextAttributeTextColor,
                nil
        ]
];

NSDictionary* actionStyle = [NSDictionary 
    dictionaryWithObjects:[NSArray 
        arrayWithObjects:
            [UIColor greenColor],
            nil
        ]
        forKeys:[NSArray
            arrayWithObjects:
                UITextAttributeTextColor,
                nil
        ]
]; 

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationController class], nil] 
    setTitleTextAttributes:buttonStyle
    forState:UIControlStateNormal
];

[[ActionBarButtonItem appearanceWhenContainedIn:[UINavigationController class], nil]
    setTitleTextAttributes:actionStyle
    forState:UIControlStateNormal
];

理论上,灰色文本将应用于所有 UIBarButtonItems。然后我只为 ActionBarButtonItems 用绿色文本覆盖灰色文本。最终结果并不如预期。由于未知原因,每个 UIBarButtonItem 都会获得绿色文本。为什么?

【问题讨论】:

    标签: iphone ios cocoa-touch


    【解决方案1】:

    您正在对UIBarButton 进行子类化,所以我最初的想法是,当您在ActionBarButtonItem 上调用appearanceWhenContainedIn 时,结果是对超类appearanceWhenContainedIn 的调用,因此这就是发生这种情况的原因。这并不理想,但您可以更改加载视图上左右项目的外观,或者视图将出现在每个视图中。

    NSDictionary* buttonStyle = [NSDictionary 
                                     dictionaryWithObjects:[NSArray 
                                                            arrayWithObjects:
                                                            [UIColor blueColor],nil]
                                     forKeys:[NSArray
                                              arrayWithObjects:
                                              UITextAttributeTextColor,
                                              nil
                                              ]
                                     ];
    
    NSDictionary* actionStyle = [NSDictionary 
                                 dictionaryWithObjects:[NSArray 
                                                        arrayWithObjects:
                                                        [UIColor greenColor],
                                                        nil
                                                        ]
                                 forKeys:[NSArray
                                          arrayWithObjects:
                                          UITextAttributeTextColor,
                                          nil
                                          ]
                                 ]; 
    
    
    
    [self.navigationItem.leftBarButtonItem setTitleTextAttributes:buttonStyle forState:UIControlStateNormal];
    [self.navigationItem.rightBarButtonItem setTitleTextAttributes:actionStyle forState:UIControlStateNormal];
    

    你也可以选择把它放在某个地方,比如你的应用程序委托,这样你就可以使用[[UIApplication sharedApplication].delegate setBarButtonColors] 更简单地访问它。 另一种选择可能是UINavigationBar 上的类别。

    【讨论】:

    • 我有一个名为 TableViewControllerStyled 的超类,我所有的页面都来自它。我把你的代码放在它的 viewDidLoad 方法中。我没有看到文字颜色被改变。我确保您的代码是使用断点运行的。我相信每次系统在导航栏中放置一个按钮时,它都会创建一个新按钮。所以风格不会被继承。
    • 我用您的部分解决方案解决了这个问题。我创建了一个UIBarButtonItem+style 类别。在其中,我有一个 actionButtonTitle:target:action: 静态方法,它创建一个具有正确样式的自动释放按钮。每当我需要rightBarButtonItem 时,我都会使用此方法。我可以继续使用UIAppearance 来设置leftBarButtonItem 的样式。我的特殊按钮将覆盖UIApperance 应用的全局UIBarButtonItem 样式。
    • 是的,听起来不错,一个类别是更好的选择,不过我应该很高兴能提供一些帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2021-09-23
    • 2018-09-10
    • 1970-01-01
    相关资源
    最近更新 更多