使用啥控件从相机捕获图像并在 ui 上显示为带有事件 xamarin ios 的缩略图

Posted

技术标签:

【中文标题】使用啥控件从相机捕获图像并在 ui 上显示为带有事件 xamarin ios 的缩略图【英文标题】:What control to use to capture image from camera and show on ui as thumbnail with events xamarin ios使用什么控件从相机捕获图像并在 ui 上显示为带有事件 xamarin ios 的缩略图 【发布时间】:2019-06-26 13:20:08 【问题描述】:

我在我的 xamarin ios 移动项目中创建了这样的视图。

用户将能够单击捕获图像按钮来拍照并设置图像视图的图像属性。我想知道如何允许用户长按图像(在捕获图像之后)并弹出一个消息框以删除图像。

我已经尝试过 Sameer 在我的 ViewDidLoad 中的评论中提出的建议

    var gestureRecognizer = new UILongPressGestureRecognizer();
    gestureRecognizer.AddTarget(() => ButtonLongPressed(gestureRecognizer));
    img1.AddGestureRecognizer(gestureRecognizer);
    img2.AddGestureRecognizer(gestureRecognizer);

当我单击并按住图像时,没有任何反应。我已经通过设计器添加了这些图像视图。

经过更多研究并使用@Junior Jiang - MSFT 的评论。我已经取得了一些进展,但我想知道点击了哪个 UIImage 视图。

这是我当前的代码:

 public JobImagesViewController(Job passedInCurrentJob) : base("JobImagesViewController", null)
        
            currentJob = passedInCurrentJob;
            uIImageViews = new List<UIImageView>();           
        

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

            uIImageViews.Add(img1);
            uIImageViews.Add(img2);
            uIImageViews.Add(img3);
            uIImageViews.Add(img4);
            uIImageViews.Add(img5);
            uIImageViews.Add(img6);
            uIImageViews.Add(img7);
            uIImageViews.Add(img8);
            uIImageViews.Add(img9);
            uIImageViews.Add(img10);

            InitialiseImageGrid();

            // Add a Save button to the navigation bar
            this.NavigationItem.SetRightBarButtonItem(
                new UIBarButtonItem("Save", UIBarButtonItemStyle.Done, (sender, args) =>
                
                    //TODO if else block with all logic to check if there are images etc.
                    //TODO prompt user and ask if they would like to save images.
                    UIAlertView alert = new UIAlertView("Save Images?", "Save images against the Job?", null, "Yes", new string[]  "No" );
                    alert.Clicked += (s, e) =>
                    
                        if (e.ButtonIndex == 0) // Yes clicked
                        
                            SaveJobImages();
                        
                    ;
                    alert.Show();

                ), true);

        


   [Export("ImageLongPressed:")]
        public void ImageLongPressed(UILongPressGestureRecognizer gestureRecognizer)
        
            if (gestureRecognizer.State != UIGestureRecognizerState.Began)
            
                return;
                // Needed because selector is executed twice, because Long-press gestures are continuous
            
            // Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image
            UIAlertView alert = new UIAlertView("Delete this image ?" , "Are you sure you want to delete this image?", null, "Yes", new string[]  "No" );
            alert.Clicked += (s, e) =>
            
                if (e.ButtonIndex == 0) // 'Accept' clicked
                
                    // TODO how to get the image which has been clicked??
                
            ;
            alert.Show();

        


        private void InitialiseImageGrid()
        
            _imageList = DataAccess.GetImages(currentJob.jobAddressID);
            var imageBytes = _imageList.Select(x => x.ImageBytes).ToList();

            var gestureRecognizer = new UILongPressGestureRecognizer(this, new ObjCRuntime.Selector("ImageLongPressed:"));
            gestureRecognizer.AddTarget(() => ImageLongPressed(gestureRecognizer));

            // Populate the image views.
            // TODO need to find a way to assign it to every imageview on the view without looping maybe linq???
            int i = 0;
            foreach (var item in imageBytes)
            
                var imagedata = NSData.FromArray(item);
                var img = UIImage.LoadFromData(imagedata);

                if (uIImageViews != null && uIImageViews.Count > i)
                
                    uIImageViews[i].UserInteractionEnabled = true;
                    uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
                    uIImageViews[i].AddGestureRecognizer(gestureRecognizer);
                    uIImageViews[i].Image = img;
                
                i++;

        

【问题讨论】:

【参考方案1】:

这取决于您创建视图的方式,您是否使用带有所有图像的XIB 作为带有图像的按钮,以及连接到这些按钮的IBActions。只需将发件人设为UILongPressGestureRecognizer

如果您是通过代码执行此操作,那么在您的ViewDidLoad 中,您希望将按钮设置为具有首字母 ? (或需要图像)背景图像,然后将UILongPress GestureRecognizer 添加到它们中的每一个。所以如果你有一个按钮,你会这样做:

public override void ViewDidLoad ()

    // Perform any additional setup after loading the view

    UIButton button = new UIButton (new System.Drawing.RectangleF(100, 100, 100, 30));
    button.SetBackgroundImage ("imageNeeded", UIControlState.Normal);
    var gestureRecognizer = new UILongPressGestureRecognizer ();
    gestureRecognizer.AddTarget(() => this.ButtonLongPressed(gestureRecognizer));
    button.AddGestureRecognizer(gestureRecognizer);
    this.View.Add (button);


public void ButtonLongPressed(UILongPressGestureRecognizer gestureRecognizer)

    if (gestureRecognizer.State != UIGestureRecognizerState.Began) 
    
          return;
          // Needed because selector is executed twice, because Long-press gestures are continuous
    
    // Perform action of opening the dialog to select/take a picture, replacing the ? image with the new image

【讨论】:

@Sameer - 我计划在屏幕上设置带有示例图像的按钮。用户可以点击按钮打开摄像头并设置图像。我可以为所有按钮设置一个单击事件,而不是为 10 个按钮设置 10 个事件。当用户想删除图片时,我一定会尝试您的代码。 由于您想要做的工作因人而异,并且由于它不完全是一个事件,因此您必须创建单独的 GestureRecognizers @Sameer - 我稍微改变了计划,我添加了一个按钮“捕获图像”和 10 个 UIImageviews。当用户单击捕获按钮时,我会浏览每个图像视图并查看哪个是免费的并相应地设置图像。但是,我无法按照您在代码中的建议设置长按手势。顺便说一下,我已经通过设计师添加了图像视图。 @Sameer - 我现在更新了我的问题。谢谢。【参考方案2】:

如果要在UIImage中使用UILongPressGestureRecognizer,应将ImageView的UserInteractionEnabled设置为true

如下:

List<UIImageView> imageViews = new List<UIImageView>();

UIImage image = UIImage.FromFile("off.png");
ImageViewOne.Image = image;
ImageViewOne.Tag = 1;
ImageViewTwo.Image = image;
ImageViewTwo.Tag = 2;

imageViews.Add(ImageViewOne);
imageViews.Add(ImageViewTwo);

foreach (var imageview in imageViews)

    imageview.UserInteractionEnabled = true;
    UILongPressGestureRecognizer uITapGestureRecognizer = new UILongPressGestureRecognizer();
    uITapGestureRecognizer.AddTarget(() =>  Console.WriteLine("You choose View " + imageview.Tag); );
    imageview.AddGestureRecognizer(uITapGestureRecognizer);

这是来自 Apple 的 official document。

【讨论】:

感谢您的评论,我已设置 UserInteractionenabled = true;在代码和控件属性中。您评论中的代码出现在我的 ViewDidLoad() 方法中。而且 ButtonLongPressed 永远不会被解雇。我错过了什么?? @Abe Okey ,您可以显示有关该部分的完整代码,或者分享一个示例,我会检查一下。 感谢您的评论。我已经取得了一些进展,我能够捕捉到长按手势但是我无法找出按下了哪个 UIImageview。 @Abe 您可以为每个ImageView设置Tag,我会更新答案。如果有帮助,感谢您提前标记。

以上是关于使用啥控件从相机捕获图像并在 ui 上显示为带有事件 xamarin ios 的缩略图的主要内容,如果未能解决你的问题,请参考以下文章

从相机捕获图像并在活动中显示

通过相机扫描图像和从相机捕获图像之间有啥不同吗?

在屏幕上显示从相机捕获的图像时的混乱

gtk 图像突然不刷新没有任何错误或警告

gtk图像突然不刷新没有任何错误或警告

从相机捕获图像并保存