19

我正在尝试在 UINavigationBar 中添加一个自定义控件作为 titleView。当我这样做时,尽管设置了通常假定全宽的框架和属性,但我得到了这个: 替代文字

可以忽略亮蓝色,因为它是我隐藏自定义控件的地方。问题是导航栏末端的窄条。我怎样才能摆脱这些,所以我的自定义视图将伸展 100%?

CGRect frame = CGRectMake(self.view.bounds.origin.x, self.view.bounds.origin.y, self.view.width, kDefaultBarHeight);
UANavBarControlView *control = [[[UANavBarControlView alloc] initWithFrame:frame] autorelease];
control.autoresizingMask = UIViewAutoresizingFlexibleWidth; 
self.navigationItem.titleView = control;

PS - 我知道我可以自己添加视图而不是附加到导航栏,而且我自己定位它会很容易。我有理由需要它“在”导航栏上,这些原因就在这里

4

6 回答 6

28

刚遇到同样的问题,经过一番思考解决了。titleView 的框架在每次出现时由 navigationBar 设置。

您所要做的就是继承 UIView 和 override setFrame

像这样:

    - (void)setFrame:(CGRect)frame {
        [super setFrame:CGRectMake(0.0, 0.0, 320.0, 50.0)];
    }

现在将你鬼鬼祟祟的新 UIView 设置为navigationItem.titleView并享受它对超级视图调整大小的新阻力。

每次设置框架时,您都不必设置 super 的框架。您只需设置一次即可完成。如果您想支持方向更改,您也可以将其组合在一起。

于 2012-03-29T12:12:46.080 回答
25

设置视图的 navigationItem 的 titleView 永远不会成功。相反,您可以将 subView 添加到导航控制器的 navigationBar :

UIView* ctrl = [[UIView alloc] initWithFrame:navController.navigationBar.bounds];
ctrl.backgroundColor = [UIColor yellowColor];
ctrl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[navController.navigationBar addSubview:ctrl];
于 2010-09-23T12:16:17.753 回答
4

下面的代码写在iOS8/iOS9/iOS10/iOS11 上

swift 3中的代码

class TitleView: UIView {

    override var frame: CGRect {
        get {
            return super.frame
        }
        set {
            super.frame = newValue.insetBy(dx: -newValue.minX, dy: 0)
        }
    }

    override func didMoveToSuperview() {
        if let superview = superview {
            frame = superview.bounds
            translatesAutoresizingMaskIntoConstraints = true
            autoresizingMask = [.flexibleWidth, .flexibleHeight]
        }
    }

    override func updateConstraints() {
        super.updateConstraints()
        /// remove autolayout warning in iOS11
        superview?.constraints.forEach { constraint in
            if fabs(constraint.constant) == 8 {
                constraint.isActive = false
            }
        }
    }
}
于 2017-09-19T06:50:06.787 回答
1

ksm 答案的 Swift 版本

let leftOffset: CGFloat = 60
let rightOffset: CGFloat = 60

@objc override var frame: CGRect {
     didSet {
                let width: CGFloat = UIScreen.main.bounds.width - leftOffset - rightOffset
                let height: CGFloat = 44

                super.frame = CGRect(
                    x: leftOffset,
                    y: 20,
                    width: width,
                    height: height
                )
       }
}
于 2017-06-05T01:34:26.097 回答
0

感谢@VdesmedT您的回答,我一直在使用这个答案在导航栏中实现全屏大小的标题视图。

但是,我最近刚升级到iOS11,发现这个解决方案不起作用。所以我用另一种方式想通了(可能看起来很奇怪)。核心思想不是改变titleView的大小,而是改变bar的subViews来实现全屏bar的影响

  1. 制作一个 barView(确保 barView 宽度为 screenSize - 12*2,12 是系统填充设置为 titleView,您可以使用手动布局或自动布局的约束来实现这一点)。然后将其设置为导航栏的titleView
  2. 将您的组件添加到此 barView 中。您可以将组件从 -12 对齐到 barView 的宽度 + 12
  3. 重载 barView 的 pointInside ,即使点击发生在 barView 之外,它也可以响应。

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
     {
      BOOL ret = [super pointInside:point withEvent:event];
      if (ret == NO)
      {
        CGRect expandRect = UIEdgeInsetsInsetRect(self.bounds, UIEdgeInsetsMake(0, -12, 0, -12));
        ret = CGRectContainsPoint(expandRect, point);
    }
    return ret;
    }
    
于 2017-07-18T07:40:44.110 回答
-7

CGRect 框架 = CGRectMake(0, 0, 320, 44);

UILabel *titlelabel = [[UILabel alloc]initWithFrame:frame];

titlelabel.textAlignment = UITextAlignmentCenter;

titlelabel.backgroundColor = [UIColor clearColor];

titlelabel.textColor = [UIColor whiteColor];

titlelabel.font = [UIFont systemFontOfSize:20];

titlelabel.text =@"Available Reports";

self.navigationItem.titleView = titlelabel;

如果你想设置图像,然后在 uilable 上取 uiimage 视图,你可以创建完整导航栏的任何视图,只需告诉我你的导航看起来如何,如果你愿意,我会向你发送代码,我也可以在导航上放置 6 个按钮

于 2010-10-04T06:03:43.380 回答