如何给UINavigationBar添加按钮

如何给UINavigationBar添加按钮,第1张

 Mads Mobæk:给UINavigationBar添加按钮的示例代码

12345678UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"style:UIBarButtonItemStyleDone target:nil action:nil]UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:@"Title"]item.rightBarButtonItem = rightButtonitem.hidesBackButton = YES[bar pushNavigationItem:item animated:NO][rightButton release][item release]

但是通常你得有一个Navigation Controller,使你能够写如下代码:

1234UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done"style:UIBarButtonItemStyleDone target:nil action:nil]self.navigationItem.rightBarButtonItem = rightButton[rightButton release]

Amagrammer:楼上的回答非常好,我想再提一些建议:

如果修改后退按钮的标题,必须在先前的view controller里修改,而不是在将要显示的地方修改。就像是说“hey,如果你曾在这个上面放置另一个view controller,那就把后退按钮称为back,而不是default(默认)”。

如果你想在某个特殊状态下隐藏后退按钮,比如显示UIPickerView时,使用self.navigationItem.hidesBackButton = YES当你退出这一状态时,记得设置回原样。

如果你想显示某个特殊的象征性按钮,使用带有UIBarButtonSystemItemAdd这类控件的initWithBarButtonSystemItem:target:action方法

记住,符号的意义是由你决定的,但是要小心人机界面交互指南。使用UIBarButtonSystemItemAdd意味着删除一个项目将可能导致你的应用被拒。

1.在固定位置添加UIBarButtonItem

view plaincopy to clipboardprint?

UIBarButtonItem *myButton = [[[UIBarButtonItem alloc]

initWithTitle:@"myButton"

style:UIBarButtonItemStyleBordered

target:self

action:@selector(action)]autorelease]

self.navigationItem.leftBarButtonItem = myButton

//self.navigationItem.rightBarButtonItem = myButton

//self.navigationItem.backBarButtonItem = myButton

[myButton release]

NavigationItem类有以下一些成员:

-title

-titleview

-backBarButtonItem//这是有返回上一级事件的后退按钮

-rightBarButtonItem

-leftBarButtonItem

2.在任意位置添加一个UIToolbar叠加到navigationBar上,然后设置其背景透明,则可以实现在上这个navigationBar 上面添加多个按钮的效果

view plaincopy to clipboardprint?

UIToolbar *mycustomToolBar

NSMutableArray *mycustomButtons = [[NSMutableArray alloc] init]

UIBarButtonItem *myButton1 = [[[UIBarButtonItem alloc]

initWithTitle:@"Get5"

style:UIBarButtonItemStyleBordered

target:self

action:@selector(action)]autorelease]

myButton1.width = 40

[mycustomButtons addObject: myButton1]

UIBarButtonItem *myButton2 = [[[UIBarButtonItem alloc]

initWithTitle:@"Play5"

style:UIBarButtonItemStyleBordered

target:self

action:@selector(action)]autorelease]

myButton2.width = 40

[mycustomButtons addObject: myButton2]

mycustomToolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f,320.0f, 44.0f)]

//mycustomToolBar.center = CGPointMake(160.0f,200.0f)

mycustomToolBar.barStyle = UIBarStyleDefault

[mycustomToolBar setItems:mycustomButtons animated:YES]

[mycustomToolBar sizeToFit]

[self.view addSubview:mycustomToolBar]

//self.navigationItem.titleView = mycustomToolBar//与上一句都可实现在上面叠加工具条

//将toolbar的颜色设置为透明,总之使用两个控件叠加完美

[mycustomToolBar release]

[mycustomButtons release]

这里是在UIToolbar 上面添加UIBarButtonItem,然而我们很多时候可能会添加其它控件,如:switch,label等等,所以在UIToolbar上面如何添加各种控件,就参考下一篇文章。

3.在任意位置添加UISegmentedControl

view plaincopy to clipboardprint?

UISegmentedControl * mySegment

mySegment = [[UISegmentedControl alloc]

initWithFrame:CGRectMake(5.0f, 10.0, 60.0f, 30.0f)]

[mySegment insertSegmentWithTitle:@"mySeg1" atIndex:0 animated:YES]

[get5Segment insertSegmentWithTitle:@"mySeg2" atIndex:1 animated:YES]

mySegment.segmentedControlStyle = UISegmentedControlStyleBar

[mySegment addTarget:self action:@selector(segAction:) forControlEvents:UIControlEventValueChanged]

mySegment.selectedSegmentIndex = -1

[self.navigationController.navigationBar addSubview: mySegment]

[mySegment release]

如果要在navigationBar实现多个按钮,而且某个功能块的类似按钮需要挨在一起,用segment实现还是很不错,用UIBarButtonItem实现的话,按钮间总是有一个间隔。

4.在任意位置添加UILabel

view plaincopy to clipboardprint?

UILabel* myLabel

myLabel=[[UILabel alloc] initWithFrame:CGRectMake(100.0f, 14.0f, 100.0f, 10.0f)]

myLabel.font=[UIFont systemFontOfSize:10]

myLabel.backgroundColor = [UIColor clearColor]

[self.navigationController.navigationBar addSubview: myLabel]

[myLabel release]

5.在任意位置添加UIProgressView

view plaincopy to clipboardprint?

UIProgressView *myProgress

myProgress =[[UIProgressView alloc] initWithFrame:CGRectMake(80.0f, 28.0f, 150.0f, 8.0f)]

[self.navigationController.navigationBar addSubview: myProgress]

[myProgress release]

(转载)

我们使用的大多数android手机上的Home键,返回键以及menu键都是实体触摸感应按键。如果你用Google的Nexus4或Nexus5话,你会发现它们并没有实体按键或触摸感应按键,取而代之的是在屏幕的下方加了一个小黑条,在这个黑条上有3个按钮控件,这种设置无疑使得手机的外观的设计更加简约。但我遇到身边用Nexus 4手机的人都吐槽这种设计,原因很简单:好端端的屏幕,被划出一块区域用来显示3个按钮(如下图所示):Back, Home, Recent。并且它一直用在那里占用着。

在android源码中,那一块区域被叫做NavigationBar。同时,google在代码中也预留了标志,用来控制它的显示与隐藏。NavigationBar的显示与隐藏的控制是放在SystemU中的,具体的路径是:\frameworks\base\packages\SystemUI。对android4.0以上的手机而言,SystemUi包含两部分:StatusBar和NavigationBar。在SystemUI的工程下有一个类PhoneStatusBar.java,在该类中可以发现关于控制NavigationBar的相关代码:

在start()方法里可以看到NavigationBar是在那时候被添加进来,但只是添加,决定它显示还是隐藏是在后面控制的。

<span style="font-size:18px">@Override

public void start() {

mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))

.getDefaultDisplay()

updateDisplaySize()

/// M: Support Smartbook Feature.

if (SIMHelper.isMediatekSmartBookSupport()) {

/// M: [ALPS01097705] Query the plug-in state as soon as possible.

mIsDisplayDevice = SIMHelper.isSmartBookPluggedIn(mContext)

Log.v(TAG, "start, mIsDisplayDevice=" + mIsDisplayDevice)

}

super.start()// calls createAndAddWindows()

addNavigationBar()

// Lastly, call to the icon policy to install/update all the icons.

mIconPolicy = new PhoneStatusBarPolicy(mContext)

mHeadsUpObserver.onChange(true)// set up

if (ENABLE_HEADS_UP) {

mContext.getContentResolver().registerContentObserver(

Settings.Global.getUriFor(SETTING_HEADS_UP), true,

mHeadsUpObserver)

}

}</span>

其中的addNavigationBar()具体的实现方法如下:

<span style="font-size:18px">// For small-screen devices (read: phones) that lack hardware navigation buttons

private void addNavigationBar() {

if (DEBUG) Slog.v(TAG, "addNavigationBar: about to add " + mNavigationBarView)

if (mNavigationBarView == null) return

prepareNavigationBarView()

mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams())

}</span>

可以看到Navigationbar实际上windowmanager向window窗口里添加一个view。在调用addNavigationBar()方法之前会回调start()的父方法super.start()来判断是否要添加NavigationBar。在super.start()的调用父类方法里会调用createAndAddWindows(),该方法内会判断是否需要添加显示NavigationBar,然后决定是否要实例化NavigationBarView.

<span style="font-size:18px">try {

boolean showNav = mWindowManagerService.hasNavigationBar()

if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav)

if (showNav) {

mNavigationBarView =

(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null)

mNavigationBarView.setDisabledFlags(mDisabled)

mNavigationBarView.setBar(this)

}

} catch (RemoteException ex) {

// no window manager? good luck with that

}</span>

WindowManagerService类实现了WindowManagerPolicy的接口,所以WindowManagerService会回调WindowManagerPolicy 的hasNavigationBar()接口,

<span style="font-size:18px">@Override

public boolean hasNavigationBar() {

return mPolicy.hasNavigationBar()

}</span>

Policy向下调用实际上调用的是PhoneWindowManager实现的hasNavigationBar方法,下面代码是PhoneWindowManager中的hasNavigationBar()方法。

<span style="font-size:18px">// Use this instead of checking config_showNavigationBar so that it can be consistently

// overridden by qemu.hw.mainkeys in the emulator.

public boolean hasNavigationBar() {

return mHasNavigationBar

}</span>

而mHasNavigationBar的赋值可以在PhoneWindowManager中的setInitialDisplaySize(Display display, int width, int height, int density)方法中找到,

<span style="font-size:18px">if (!mHasSystemNavBar) {

mHasNavigationBar = mContext.getResources().getBoolean(

com.android.internal.R.bool.config_showNavigationBar)

// Allow a system property to override this. Used by the emulator.

// See also hasNavigationBar().

String navBarOverride = SystemProperties.get("qemu.hw.mainkeys")

if (! "".equals(navBarOverride)) {

if (navBarOverride.equals("1")) mHasNavigationBar = false

else if (navBarOverride.equals("0")) mHasNavigationBar = true

}

} else {

mHasNavigationBar = false

}</span>

从上面代码可以看到mHasNavigationBar的值的设定是由两处决定的:

1.首先从系统的资源文件中取设定值config_showNavigationBar, 这个值的设定的文件路径是frameworks/base/core/res/res/values/config.xml

<!-- Whether a software navigation bar should be shown. NOTE: in the future this may be

autodetected from the Configuration. -->

<bool name="config_showNavigationBar">false</bool>

2.然后系统要获取“qemu.hw.mainkeys”的值,这个值可能会覆盖上面获取到的mHasNavigationBar的值。如果 “qemu.hw.mainkeys”获取的值不为空的话,不管值是true还是false,都要依据后面的情况来设定。

所以上面的两处设定共同决定了NavigationBar的显示与隐藏。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/7882952.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-11
下一篇2023-04-11

发表评论

登录后才能评论

评论列表(0条)

    保存