我正在尝试使用MonoTouch为iOS中的导航控制器创建自定义导航栏。我正在开发的应用程序需要在屏幕上显示一个字符串,无论你在应用程序的哪个位置,我都不想实现这样的东西(我知道这有点不合适,但是你应该能够明白这一点):
+-----------------------------------------+
| /---------| +---+ |
| / Back | Controller Name |btn| |
| \---------| +---+ |
+-----------------------------------------+
| Current building <- global string |
+-----------------------------------------+
底栏应尽可能小(虽然不难读),原始导航栏可能需要比正常小一点。
另外,我已经尝试过不使用设计器,而是自己编写所有的UI代码,但如果不可能实现这一点,那么我将不得不使用设计器。目前我发现了一个用于在MonoTouch中创建自定义UINavigationBar的项目,但我不知道如何将其应用于我的NavigationController(请参阅NavigationBar属性是只读的)。我在谈论的项目可以在这里找到:https://github.com/mafis/Monotouch-Custom-Control/tree/master/CustomControls。另外,我希望实际导航栏(顶部)的设计是标准的iOS设计,并且通常可以作为导航栏使用。
任何提示或指示如何做到这一点将不胜感激。
答案 0 :(得分:4)
这就是我最终解决这个问题的方法。我将UIViewController子类化为:
using System;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
using System.Drawing;
using System.Collections.Generic;
using FdvWeb.Core;
namespace FdvWeb
{
[MonoTouch.Foundation.Preserve(AllMembers=true)]
public class MainNavigationController : UINavigationController
{
private const float NAV_BAR_HEIGHT = 44;
private readonly float buildingBarTop = 44;
private readonly float buildingBarHeight = 17;
private readonly float viewOffset;
private readonly HashSet<UIViewController> modifiedViewControllers = new HashSet<UIViewController>();
UITextView buildingTextView;
[MonoTouch.Foundation.Preserve]
public MainNavigationController ()
{
viewOffset = buildingBarTop + buildingBarHeight - NAV_BAR_HEIGHT;
var tt = new UITextView (new RectangleF (0, buildingBarTop, 320, buildingBarHeight));
NavigationBarHidden = false;
NavigationBar.AddSubview (tt);
tt.Font = UIFont.BoldSystemFontOfSize (12);
tt.TextAlignment = UITextAlignment.Center;
tt.TextColor = UIColor.LightTextColor;
tt.BackgroundColor = UIColor.ViewFlipsideBackgroundColor;
tt.Editable = false;
tt.ContentInset = new UIEdgeInsets (-9, 0, 0, 0);
buildingTextView = tt;
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
}
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
}
public string BuildingText
{
get {
return buildingTextView.Text;
}
set {
container.Resolve<IUIThreadDispatcher> ().DispatchOnUIThread (delegate { // Run on UI thread
buildingTextView.Text = value;
});
}
}
public override void PushViewController (UIViewController viewController, bool animated)
{
if (!modifiedViewControllers.Contains (viewController))
{
viewController.View = new PaddedView (viewController.View, new InnsetF (0, viewOffset, 0, 0));
modifiedViewControllers.Add (viewController);
}
viewController.NavigationItem.RightBarButtonItem = pickBuildingItem;
base.PushViewController (viewController, animated);
}
private class PaddedView : UIView
{
private UIView view;
private InnsetF innsets;
public PaddedView (UIView view, InnsetF innsets)
: base(view.Frame)
{
this.view = view;
this.innsets = innsets;
this.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
this.AddSubview (view);
}
public override void LayoutSubviews ()
{
//apply the insets to the subview
view.Frame = new RectangleF (innsets.Left, innsets.Top,
Frame.Size.Width - innsets.Left - innsets.Right,
Frame.Size.Height - innsets.Top - innsets.Bottom);
}
}
private class InnsetF
{
private float top, bottom, left, right;
public InnsetF (float left, float top, float right, float bottom)
{
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public float Top
{
get { return top; }
set { top = value; }
}
public float Bottom
{
get { return bottom; }
set { bottom = value; }
}
public float Right
{
get { return right; }
set { right = value; }
}
public float Left
{
get { return left; }
set { left = value; }
}
}
}
}
答案 1 :(得分:1)
所以你想要与Spotify离线时所做的相反(你所指的字符串信息出现在UINavigationController上面)。
我认为你所采用的方法不会起作用 - 据我所知,NavigationBar的高度只有44像素。你能采用类似的Spotify方法并将其移到NavigationBar之上吗?这样你可以保持NavigationController等原样并简单地使它的视图更小,然后将字符串添加到窗口对象 - 这样它将在你浏览应用程序时保持不变。