我有一个有趣的问题,我认为我在正确的轨道上,但需要指出正确的方向。我试图对 UITabBar 进行子类化,并希望在运行时添加一个 UIButton,该 UIButton 在标签栏“上方”偏移。我还想点击该按钮并将标签栏设置为动画进出视图。我已经看过类似的帖子,但是解决方案说将按钮添加到 UITabBarController 的视图中,而不是尝试使其在 UITabBar 中工作:
我想将它添加到 UIToolBar 或知道为什么我不应该以及为什么 UITabBarController 方法更好/更高效/更清洁,或者其他什么。这是我的 CollapsibleToolbar 实现文件(减去动画代码)。我对 iOS 还是很陌生,所以我可能会做一些非常简单的错误。
#import "CollapsibleTabBar.h"
@interface CollapsibleTabBar () {
BOOL _isCollapsed;
double _imageHeight;
double _imageWidth;
}
@property (nonatomic, retain) UIImage *buttonImage;
@property (nonatomic, retain) UIButton *slideButton;
@end
@implementation CollapsibleTabBar
@synthesize slideButton;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self){
_isCollapsed = YES;
// Place button in UI
_imageHeight = 40;
_imageWidth = 40;
// Create button image
self.buttonImage = [UIImage imageNamed:@"tab-bar-expander-button.png"];
// Create an hook up button
self.slideButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.slideButton.backgroundColor = [UIColor colorWithPatternImage:self.buttonImage];
[self.slideButton addTarget:self action:@selector(slideButtonTapped) forControlEvents:UIControlEventTouchUpInside];
// Set button frame
self.slideButton.frame = CGRectMake((self.center.x - (_imageWidth/2.0)), -1*_imageHeight, _imageWidth, _imageHeight);
double yOriginOffset = self.frame.origin.y - _imageHeight;
// Must increase the bounds to allow the slide button to receive touch events?
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height + _imageHeight);
// Add button as sub view
[self addSubview:self.slideButton];
}
return self;
}
- (void)slideButtonTapped {
// Animate that junk ...
}
- (void)dealloc{
// Remove target
[self.slideButton removeTarget:self action:@selector(slideButtonTapped) forControlEvents:UIControlEventTouchUpInside];
self.buttonImage = nil;
self.slideButton = nil;
}
我正在使用 initWithCoder,因为我在我的笔尖上拖放了一个 UITabBar,将它的类设置为 CollapsibleTabBar。我认为,initWithFrame 不会因此而触发。
无论如何,这会将按钮准确地放置在我想要的位置,但是 slideButtonTapped 方法永远不会触发。像这样更改 UIButton 的框架会将按钮的下半部分暴露给 UITabBar 的可点击区域,并且我的 slideButtonTapped 事件将触发:
self.slideButton.frame = CGRectMake((self.center.x - (_imageWidth/2.0)), -1*_imageHeight/2.0, _imageWidth, _imageHeight);
由此我知道这是一个框架/边界问题。该按钮可见但不可点击,因为它位于 UITTabBar 的某些可点击区域之外。所以我开始弄乱 UITTabBar 的框架(正如 Dave H. 建议作为上面链接中的答案)并增加它的大小以包含 UIButton 以希望按钮能够响应点击事件。
我无法正确定位 UITabBar + UIButton 的框架,即使将框架放置在超级视图中的这个 Y 位置并将其高度增加按钮的高度似乎是合乎逻辑的:
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y-_imageHeight, self.frame.size.width, self.frame.size.height + _imageHeight);
更糟糕的是,这会禁用按钮点击,并且 UITabBar 会呈现在错误的位置。我已经阅读了文档,但我还没有意识到我可能做错了什么。
其他问题:
- 这是正确的方法吗?请记住,我想支持开箱即用的旋转,而在我的视图控制器中没有混乱的帧动画代码。
- UIView 的可点击区域如何控制?那是 frame 或 bounds 属性还是其他什么?
- Apple 文档说使用 UIView 的 layoutSubviews 方法来定位超级视图的子视图。我也尝试过,行为没有区别。我应该重新考虑吗?
如果您需要查看任何其他代码,请告诉我。任何帮助将不胜感激。
上帝保佑!