1

我有一个有趣的问题,我认为我在正确的轨道上,但需要指出正确的方向。我试图对 UITabBar 进行子类化,并希望在运行时添加一个 UIButton,该 UIButton 在标签栏“上方”偏移。我还想点击该按钮并将标签栏设置为动画进出视图。我已经看过类似的帖子,但是解决方案说将按钮添加到 UITabBarController 的视图中,而不是尝试使其在 UITabBar 中工作:

将 UIButton 作为子视图添加到 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 方法来定位超级视图的子视图。我也尝试过,行为没有区别。我应该重新考虑吗?

如果您需要查看任何其他代码,请告诉我。任何帮助将不胜感激。

上帝保佑!

4

0 回答 0