C# 如何以编程方式为iOS正确地将UI元素添加到视图中?

C# 如何以编程方式为iOS正确地将UI元素添加到视图中?,c#,ios,uiview,xamarin,xamarin.ios,C#,Ios,Uiview,Xamarin,Xamarin.ios,我正在使用Visual Studio 2013中的Xamarin.iOS以编程方式在C#中构建一个简单的用户界面。我知道使用designer视图要容易得多,但它现在对我不起作用 到目前为止,我已经设法让MPMoviePlayerController和TextView显示,但TextView不会滚动,尽管我添加了这样做的要求 文本视图与视频重叠,因为我可以听到背景中播放的音频。而UILabel在哪里也看不见 我认为添加每个UI元素作为主视图的子视图,将以堆栈顺序显示元素,在顶部显示视频,在视频和文

我正在使用Visual Studio 2013中的Xamarin.iOS以编程方式在C#中构建一个简单的用户界面。我知道使用designer视图要容易得多,但它现在对我不起作用

到目前为止,我已经设法让MPMoviePlayerController和TextView显示,但TextView不会滚动,尽管我添加了这样做的要求

文本视图与视频重叠,因为我可以听到背景中播放的音频。而UILabel在哪里也看不见

我认为添加每个UI元素作为主视图的子视图,将以堆栈顺序显示元素,在顶部显示视频,在视频和文本视图的右下方添加标签并滚动

在某种程度上,我想让它们一层一层地堆叠在一起。什么是我做得不对或者我遗漏了什么

using System;
using System.Drawing;

using Foundation;
using UIKit;
using MediaPlayer;

public partial class VideoViewController : UIViewController
    {
        MPMoviePlayerController moviePlayer;
        UILabel label;
        UITextView textView;
        public VideoViewController() : base("VideoViewController", null)
        {
        }

        public override void DidReceiveMemoryWarning()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning();

            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Perform any additional setup after loading the view, typically from a nib.
            moviePlayer = new MPMoviePlayerController(NSUrl.FromString("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")); // Use FromString() to play video directly from web.
            moviePlayer.View.Frame = new CoreGraphics.CGRect(0, 20, this.View.Frame.Size.Width, 180); // size of the video frame
            moviePlayer.ScalingMode = MPMovieScalingMode.AspectFit; // show the video relative to the video size dimensions
            moviePlayer.PrepareToPlay();
            moviePlayer.Play();
            this.View.AddSubview(moviePlayer.View); // add the view after video starts playing to display it

            // UILabel
            label = new UILabel();
            label.Text = "Tutorial";
            label.Font.WithSize(36);
            this.View.AddSubview(label.ViewForBaselineLayout);

            // UITextView
            textView = new UITextView();
            textView.Editable = false;
            textView.ScrollEnabled = true;
            textView.UserInteractionEnabled = true;
            textView.ViewForBaselineLayout.Frame = new CoreGraphics.CGRect(0, 0, this.View.Frame.Size.Width, this.View.Frame.Size.Height*3);
            textView.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. [shorten text for this post] "; // shorten text for this post
            this.View.AddSubview(textView);

        }
    }
}

我猜你希望它是这样的:

using System;
using System.Drawing;

using Foundation;
using UIKit;
using MediaPlayer;
using CoreGraphics;

namespace CHANGE_THIS_TO_YOUR_NAME_SPACE
{
    public partial class VideoViewController : UIViewController
    {
        MPMoviePlayerController moviePlayer;
        UILabel label;
        UITextView textView;

        public VideoViewController () : base ("VideoViewController", null)
        {
        }

        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Perform any additional setup after loading the view, typically from a nib.
            moviePlayer = new MPMoviePlayerController (NSUrl.FromString ("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")); // Use FromString() to play video directly from web.
            moviePlayer.View.Frame = new CGRect (0, 20, View.Frame.Size.Width, 180); // size of the video frame
            moviePlayer.ScalingMode = MPMovieScalingMode.AspectFit; // show the video relative to the video size dimensions
            moviePlayer.PrepareToPlay ();
            moviePlayer.Play ();
            View.Add (moviePlayer.View); // add the view after video starts playing to display it

            // UILabel
            label = new UILabel (new CGRect(0,200, View.Frame.Size.Width, 50));
            label.Text = "Tutorial";
            label.Font.WithSize (36);
            View.Add (label.ViewForBaselineLayout);

            // UITextView
            textView = new UITextView ();
            textView.Editable = false;
            textView.ScrollEnabled = true;
            textView.UserInteractionEnabled = true;
            textView.ViewForBaselineLayout.Frame = new CGRect (0, 250, View.Frame.Size.Width, View.Frame.Size.Height * 3);
            textView.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. [shorten text for this post] "; // shorten text for this post
            View.Add (textView);

        }
    }
}
基本上,当您使用
CGRect
its
newcgrect(x-coord,y-coord,width,height)
设置视图的框架时,您就快到了。由于所有视图均为0,0,因此它们被放置在彼此的顶部。另外,
UITextView
也不会滚动,因为它的高度是屏幕高度的三倍。如果要滚动内容(文本),则需要将其延伸到框架之外

引入iOS9
UIStackView
请参阅WWDC 2015的视频:但如果您支持iOS7/8,则有一些第三方实现。Forms有一个stacklayout,所以这可能也是一个选项

改进的解决方案是不设置视图的框架,而是使用自动布局约束,如下所示:

using System;
using System.Drawing;

using Foundation;
using UIKit;
using MediaPlayer;
using CoreGraphics;

namespace CHANGE_THIS_TO_YOUR_NAME_SPACE
{
    public partial class VideoViewController : UIViewController
    {
        MPMoviePlayerController moviePlayer;
        UILabel label;
        UITextView textView;

        public VideoViewController () : base ("VideoViewController", null)
        {
        }

        public override void DidReceiveMemoryWarning ()
        {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Perform any additional setup after loading the view, typically from a nib.
            moviePlayer = new MPMoviePlayerController (NSUrl.FromString ("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")); // Use FromString() to play video directly from web.
            moviePlayer.View.TranslatesAutoresizingMaskIntoConstraints = false;
//          moviePlayer.View.Frame = new CGRect (0, 20, View.Frame.Size.Width, 180); // size of the video frame
            moviePlayer.ScalingMode = MPMovieScalingMode.AspectFit; // show the video relative to the video size dimensions
            moviePlayer.PrepareToPlay ();
            moviePlayer.Play ();
            View.Add (moviePlayer.View); // add the view after video starts playing to display it

            // UILabel
//          label = new UILabel (new CGRect(0,200, View.Frame.Size.Width, 50));
            label = new UILabel ();
            label.TranslatesAutoresizingMaskIntoConstraints = false;
            label.Text = "Tutorial";
            label.Font.WithSize (36);
            View.Add (label.ViewForBaselineLayout);

            // UITextView
            textView = new UITextView ();
            textView.TranslatesAutoresizingMaskIntoConstraints = false;
            textView.Editable = false;
            textView.ScrollEnabled = true;
            textView.UserInteractionEnabled = true;
//          textView.ViewForBaselineLayout.Frame = new CGRect (0, 250, View.Frame.Size.Width, View.Frame.Size.Height * 3);
            textView.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. [shorten text for this post] "; // shorten text for this post
            View.Add (textView);

            SetUpAutoLayoutConstraints ();
        }

        private void SetUpAutoLayoutConstraints()
        {
            View.AddConstraints (new [] {
                NSLayoutConstraint.Create(moviePlayer.View, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0),
                NSLayoutConstraint.Create(moviePlayer.View, NSLayoutAttribute.Height, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 0.5625f, 0), // setting it to this to keep your aspect ratio
                NSLayoutConstraint.Create(moviePlayer.View, NSLayoutAttribute.Top, NSLayoutRelation.Equal, View, NSLayoutAttribute.Top, 1, 20),
                NSLayoutConstraint.Create(moviePlayer.View, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 0)
            });

            View.AddConstraints (new [] {
                NSLayoutConstraint.Create(label, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0),
                NSLayoutConstraint.Create(label, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 50),
                NSLayoutConstraint.Create(label, NSLayoutAttribute.Top, NSLayoutRelation.Equal, moviePlayer.View, NSLayoutAttribute.Bottom, 1, 0),
                NSLayoutConstraint.Create(label, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 0)
            });

            View.AddConstraints (new [] {
                NSLayoutConstraint.Create(textView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, View, NSLayoutAttribute.Width, 1, 0),
                NSLayoutConstraint.Create(textView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, 0),
                NSLayoutConstraint.Create(textView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, label, NSLayoutAttribute.Bottom, 1, 0),
                NSLayoutConstraint.Create(textView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 0)
            });

        }
    }
}
这样,您的视图就可以适当地适应屏幕大小,例如iphone4、5、6、6+iPad上的布局。如果您的
UITextView
太大,它将滚动显示


关于自动布局的一个很好的教程

尝试为所有UI组件设置框架,就像您对播放器所做的那样,如果框架未定义,结果将是不可预测的。感谢您的清理!但是,屏幕上没有显示任何内容(只有一个白色的空白屏幕)。我很困惑。这很奇怪,您可以尝试删除类声明中的
部分
部分,然后删除xib文件和designer.cs文件,因为您在以编程方式设置视图时不需要这些文件。如果这不起作用,你能在添加视图的地方编辑你的问题吗?再次感谢你的慷慨帮助。现在一切正常。