MonoTouch UIScrollView不能使用动态UILabel高度滚动

时间:2012-09-18 05:02:45

标签: uiscrollview xamarin.ios height uilabel

我有一个UILabel(名为contentLbl),它将在UIScrollView中动态更改。上面是另一个UILabel(名为contentTitleLbl),它是一个标题,不包含动态内容。要成功滚动,我知道我必须至少将UIScrollView的ContentSize设置为内容视图的ContentSize。我也看到应该设置框架。我试过了两个但它仍然没有滚动。

在我的示例代码中,contentView包含contentLbl和contentTitleLbl。 scrollView是我目前正在尝试使用的UIScrollView的引用。

这是我目前的代码:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    //contentLbl is to have dynamic text, and currently stores a large lorem ipsum paragraph
    //contentTitleLbl is the title and is not dynamic
    this.contentLbl.SizeToFit();
    this.scrollView.ContentSize = new SizeF(this.contentView.Frame.Width, this.contentLbl.Frame.Size.Height + this.contentTitleLbl.Frame.Size.Height);
    this.scrollView.Frame = new RectangleF(this.scrollView.Frame.X, this.scrollView.Frame.Y, this.scrollView.ContentSize.Width, this.scrollView.ContentSize.Height);
    this.scrollView.AddSubview(this.contentView);
}

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

快速提问:您是否打算将标题滚动到文字中?在这个解决方案中,我已经这样做了,因为这是我的解释。如果你愿意,我会调整它,因为标题不能滚动。 我通过在XCode

中创建此层次结构来重新创建样本
  • UIView(视图控制器的主视图)
    • UIView(contentView)
      • UILabel(contentTitleLbl)
        • Frame =(20,15,160,21)
      • UILabel(contentLbl)
        • 行= 100
        • Frame =(20,43,160,190)
        • Text =“Lorem ipsum ......”(长段)
    • UIScrollView(scrollView)
      • Frame =(20,20,140,​​140)

我将所有项目的背景颜色设置为不同的值,以便我可以看到所有组件的尺寸。

首先,我需要确保所有标签的自动调整大小都已关闭。您可以在XCode中或以编程方式执行此操作:

contentLbl.AutoresizingMask = UIViewAutoresizing.None;
contentTitleLbl.AutoresizingMask = UIViewAutoresizing.None;

我希望通过XCode将contentView放在scrollView内,但看起来你将它们作为主View下的兄弟姐妹。因此,我们重新定位contentView以将其置于scrollView

scrollView.AddSubview( contentView );

然后使标题与scrollView的宽度相同,将其定位在原点并保留XCode中设计的高度

var f = contentTitleLbl.Frame;
f.X = 0;
f.Y = 0;
f.Width = scrollView.Frame.Width;
contentTitleLbl.Frame = f;

然后是第一个主要问题:调整UILabel的大小以动态调整您的内容。 SizeToFit将标签大小调整为单行文本(或者至少为我做了)。你真正想要的是NSString.sizeWithFont appears in MonoTouch as UIView.StringSize。请注意,因为其中一些返回单行文本的大小。在这里,我将宽度约束到滚动视图的宽度,但使用float.MaxValue使高度无限制。

SizeF sz = this.View.StringSize(
    contentLbl.Text,
    contentLbl.Font,
    new SizeF( scrollView.Frame.Width, float.MaxValue),
    UILineBreakMode.WordWrap );

然后调整大小并将标签放在标题下方:

f = contentLbl.Frame;
f.X = 0;
f.Y = contentTitleLbl.Frame.Bottom; // nudge the contentLbl right up against the title
f.Width = sz.Width;    // size matches the measured values from above
f.Height = sz.Height;
contentLbl.Frame = f;

然后调整contentView的大小以保存标题和内容。此视图将放置在滚动视图的原点。大小由上面的代码动态确定。我在底部添加了一个小的边距,所以我可以告诉整个内容已经呈现

f = contentView.Frame;
f.X = 0;
f.Y = 0;
f.Width = scrollView.Frame.Width;
f.Height = contentLbl.Frame.Bottom + 20;
contentView.Frame = f;

然后将滚动视图的ContentSize设置为contentView的大小。如果大小大于而不是滚动视图的大小 - 应该是Lorem Ipsum文本的大小写 - 那么您将进行滚动。

scrollView.ContentSize = contentView.Frame.Size;

干杯。

[编辑:修正了'宽度'与'高度'的拼写错误]

[编辑:最简单的滚动视图]

这是我能想到的最简单的滚动视图。在红色区域上下拖动应显示滚动条。当你到达底部时,滚动视图的绿色背景应显示。

var v =  new UIView( new RectangleF(0,0,200,1000));
v.BackgroundColor = UIColor.Red;

var sv = new UIScrollView( new RectangleF(20,20,200,300));
sv.BackgroundColor = UIColor.Green;
sv.ContentSize = v.Frame.Size;

View.AddSubview(sv);
sv.AddSubview(v);

[编辑:更简单的滚动视图] 我在XCode中创建了一个滚动视图,只是将背景颜色和内容大小设置为大于滚动视图的大小。在蓝色滚动视图上拖动时,应显示滚动条。

designerScrollView.BackgroundColor = UIColor.Blue;
designerScrollView.ContentSize = new SizeF(1000,1000);

答案 1 :(得分:0)

只需添加此方法扩展名即可。完成添加子视图后调用它。 此方法将计算新内容高度并分配给滚动视图。

public static void RecalculateContentSize (this UIScrollView scrollView)
        {
            float sizeOfContent = 0;
            float height = 0;
            for (int i = 0; i < scrollView.Subviews.Length; i++) {
                UIView view = scrollView.Subviews [i];
                height = view.Frame.Location.Y + view.Frame.Size.Height;
                if (height > sizeOfContent)
                    sizeOfContent = height;
            }

            // Set content size for scroll view
            scrollView.ContentSize = new System.Drawing.SizeF (scrollView.Frame.Size.Width, sizeOfContent);
        }