Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将UIImageView添加到UIAlertController_C#_Xamarin_Uiimageview_Uialertcontroller - Fatal编程技术网

C# 将UIImageView添加到UIAlertController

C# 将UIImageView添加到UIAlertController,c#,xamarin,uiimageview,uialertcontroller,C#,Xamarin,Uiimageview,Uialertcontroller,目标:通过子类化UIAlertController并向标题字符串添加新行字符\n,在UIAlertController的标题标签上方添加图像,为UIImageView 渴望 现在的 如您所见,我们能够成功地将图像添加到UIAlertController中,但图像没有间隔/放置在标题上方。它似乎正在添加到警报的中心。如何在UIAlertController标题上方正确放置图像 当前代码: namespace XamarinFormsApp1.Extensions { public cla

目标:通过子类化
UIAlertController
并向标题字符串添加新行字符
\n
,在
UIAlertController的
标题标签上方添加图像,为
UIImageView

渴望 现在的

如您所见,我们能够成功地将图像添加到
UIAlertController
中,但图像没有间隔/放置在标题上方。它似乎正在添加到警报的中心。如何在UIAlertController标题上方正确放置图像

当前代码:

namespace XamarinFormsApp1.Extensions
{
    public class AlertController : UIAlertController
    {
        private string originalTitle;
        private string spaceAdjustedTitle;
        private UIImageView imageView = null;
        private CoreGraphics.CGSize previousImgViewSize 
            = CoreGraphics.CGSize.Empty;
        public override UIAlertControllerStyle PreferredStyle
        {
            get
            {
                return UIAlertControllerStyle.Alert;
            }
        }

    public override string Title
    {
        get
        {
            return originalTitle;
        }
        set
        {
            if (Title != spaceAdjustedTitle ||
                string.IsNullOrEmpty(Title) || 
                string.IsNullOrEmpty(spaceAdjustedTitle))
            {
                originalTitle = value;
            }
        }
    }

    public void setTitleImage(UIImage image)
    {
        if (this.imageView == null)
        {
            UIImageView imageView = new UIImageView(image);
            this.View.AddSubview(imageView);
            this.imageView = imageView;
            return;
        }
        imageView.Image = image;
    }

    public override void ViewDidLayoutSubviews()
    {
        if (imageView == null)
        {
            base.ViewDidLayoutSubviews();
            return;
        }
        //  Adjust title if image size has changed
        if (previousImgViewSize != imageView.Bounds.Size)
        {
            previousImgViewSize = imageView.Bounds.Size;
            adjustTitle(imageView);
        }
        //  Position `imageView`
        var linesCount = newLinesCount(imageView);
        var padding = Constants.Padding(PreferredStyle);
        var x = View.Bounds.Width / 2.0;
        var y = padding + linesCount * lineHeight / 2.0;
        CoreGraphics.CGPoint cgPoint = imageView.Center;
        cgPoint.X = (nfloat)x;
        cgPoint.Y = (nfloat)y;
        imageView.Center = cgPoint;
        base.ViewDidLayoutSubviews();
    }

    private void adjustTitle(UIImageView imageView)
    {
        var linesCount = (int)newLinesCount(imageView);
        var lines = Enumerable
            .Range(1, linesCount)
            .Select(i => "\n")
            .Aggregate((c, n) => $"{c}{n}");
        spaceAdjustedTitle = lines + (originalTitle ?? "");
        Title = spaceAdjustedTitle;
    }

    private double newLinesCount(UIImageView imageView)
    {
        return Math.Ceiling(
            imageView.Bounds.Height / lineHeight);
    }

    private float lineHeight
    {
        get
        {
            UIFontTextStyle style = this.PreferredStyle
                == UIAlertControllerStyle.Alert 
                ? UIFontTextStyle.Headline 
                : UIFontTextStyle.Callout;
            return (float)UIFont
                .GetPreferredFontForTextStyle(style)
                .PointSize;
        }
    }

    struct Constants
    {
        static float paddingAlert = 22;
        static float paddingSheet = 11;
        public static float Padding(UIAlertControllerStyle style)
        {
            return style == UIAlertControllerStyle.Alert 
                ? Constants.paddingAlert 
                : Constants.paddingSheet;
        }
    }
}
}

注意:图像和
swift
解决方案的@stringCode的功劳。

UIAlertViewController并不意味着是子类

这本书的摘录说:

通过在视图上使用透明的
UIViewController
,以及具有所需布局的子视图,仍然可以获得所需的UI

您还需要将这两个属性分别设置为:
ModalTransitionStyle
ModalPresentationStyle
UIModalTransitionStyle.CrossDissolveUIModalPresentStyle.OverCurrentContext,如果希望自定义UIAlertController的行为与
UIAlertController

更新:

这就是我的意思,你可以做到:

在Main.Storyboard中,放置一个UIViewController,并根据需要更新设计。根据您在上面发布的图像,我创建了UI,如下所示:

这是一个图像,标题和消息有2个UILabel,3个按钮用于3种不同的操作(默认、销毁、取消)。所有这些控件都位于白色背景的UIView中。例如,我称之为ContentView

在UI上添加3按钮似乎是处理此问题的最简单方法,然后在即将显示警报时隐藏/显示它们。你也可以根据你想显示的动作动态创建按钮。这取决于你

创建一个ViewController类,我称之为NiceAlertController,并将其分配给故事板中的ViewController。另外,确保为所有uicontrol(标签、按钮、图像等)创建回属性(出口),以便您可以从ViewController类访问它

有关如何在设计器上使用iOS情节提要的详细信息

现在,在您的类中,您需要添加代码以使其工作

在类中,要使视图透明,需要将以下内容添加到ViewDidLoad方法中:

public override void ViewDidLoad()
{
    base.ViewDidLoad();
    this.View.BackgroundColor = UIColor.Clear.ColorWithAlpha(0.2f);
    this.View.Opaque = false;
}
此外,我们还可以模仿UIAlertController的创建方式,并创建如下方法:

public static NiceAlertController Create(string title, string message, UIImage image = null)
{
    //New instance of your ViewController UI
    var storyboard = UIStoryboard.FromName("Main", NSBundle.MainBundle);
    var alertController = storyboard.InstantiateViewController(nameof(NiceAlertController)) as NiceAlertController;

    //Using the same transition and presentation style as the UIAlertViewController
    alertController.ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve;
    alertController.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;

    //This assumes your properties are called Title, Message and Image 
    alertController.Title = title;
    alertController.Message = message;
    alertController.Image = image;

    return alertController;
}
上面使用的3个属性(标题、消息和图像)如下所示:

public new string Title { get; private set; }

public string Message { get; private set; }

public UIImage Image { get; private set; }
为什么会有这些属性?因为在创建类时,视图上的控件还不可用。只有在加载视图后,它们才可用。这就是为什么我们需要添加其他更改,如下面的更改

这里我们将为UI上的控件设置值

public override void ViewWillAppear(bool animated)
{
    base.ViewWillAppear(animated);

    this.titleLabel.Text = Title;
    this.messageLabel.Text = Message;

    //If you don't set an image while Create, it will use the default image you set on the Designer.
    if (Image != null)
    {
        this.imageView.Image = Image;
    }
}    
现在,您可以从任何其他ViewController调用此ViewController,就像调用AlertViewController一样:

private void ShowMyAlertController()
{
    var alert = NiceAlertController.Create("Hello", "My nice alert controller");
    this.PresentViewController(alert, true, null);
}
它应该是这样的:

public new string Title { get; private set; }

public string Message { get; private set; }

public UIImage Image { get; private set; }

要处理操作(点击按钮时要做什么),您可以创建以下特定方法:

public void AddDefaultAction(string title, Action action)
{
    //Logic here
}

public void AddCancelAction(string title, Action action)
{
    //Logic here
}

public void AddDestructiveAction(string title, Action action)
{
    //Logic here
}
希望这能让您了解如何创建自定义UIViewcontroller并使其看起来像UIAlertViewController


希望这能有所帮助。-

从逻辑上讲,我会遵循,但什么
视图
支持此处所需的布局
UIAlertController
可以是,但不打算是,如前所述的子类。因此,如果我们不能将
UIAlertController
用作
视图
,也不能将
子视图
用作我们正在查看的
视图。另外,您是指带有子视图的
UIAlertController
?@jth添加了一些示例代码,说明如何使用
UIViewController
使其看起来和行为类似于
UIAlertViewController