草庐IT

ios - 动态/可拖动 UIView 的自动布局

coder 2023-10-01 原文

我试图在我的 ViewController 中有一个可拖动的 UIView,最终这个 UIView 将变成一个可点击的按钮,但现在,当它被拖动到屏幕上时,我无法更新这个 View 的约束。代码如下。

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.anotherView = [[UIView alloc]init];
    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(dragging:)];
    [self.anotherView addGestureRecognizer:panRecognizer];
    [self.anotherView setBackgroundColor: [UIColor blueColor]];
    self.anotherView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.view addSubview: self.anotherView];
    [self.view bringSubviewToFront:self.anotherView];

    NSDictionary *views = @{@"subview" : self.anotherView, @"superview" : self.view};

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.anotherView
                                                          attribute:NSLayoutAttributeLeft
                                                          relatedBy:NSLayoutRelationLessThanOrEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeLeft
                                                         multiplier:1.0
                                                           constant:0]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.anotherView
                                                          attribute:NSLayoutAttributeCenterY
                                                          relatedBy:NSLayoutRelationLessThanOrEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeCenterY
                                                         multiplier:1.0
                                                           constant:0]];


    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.anotherView
                                                          attribute:NSLayoutAttributeWidth
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:Nil
                                                          attribute:NSLayoutAttributeWidth
                                                         multiplier:1.0
                                                           constant:20]];

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"V:[subview(40)]"
                               options:0
                               metrics:nil
                               views:views]];
        // add horizontal constraints

    /*[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subview(==20)]|" options:0 metrics:nil views:views]];

     // set the height of the offscreen subview to be the same as its superview

     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[subview(==40)]" options:0 metrics:nil views:views]];

     // set the location of the subview to be just off screen below the current view

     NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.anotherView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1.0 constant:self.view.bounds.size.height];
     [self.view addConstraint:constraint];*/
        //[self.anotherView pinEdges:JRTViewPinLeftEdge toSameEdgesOfView:self.view];


        // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.leftBarButtonItem = self.editButtonItem;

    UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
    self.navigationItem.rightBarButtonItem = addButton;
    self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
}

上面的代码是我在 ViewController 中设置 UIView 的方式。预计尺寸为 20x45。拖动代码如下:

-(void)dragging:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateBegan)
        {
            //NSLog(@"Received a pan gesture");
        self.panCoord = [gesture locationInView:gesture.view];
        [self.tableView setScrollEnabled:NO];

        }
    CGPoint newCoord = [gesture locationInView:gesture.view];
    float dX = newCoord.x-self.panCoord.x;
    float dY = newCoord.y-self.panCoord.y;
    CGFloat newXPoint;
    CGFloat newYPoint;

    gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX, gesture.view.frame.origin.y+dY, gesture.view.frame.size.width, gesture.view.frame.size.height);
    if (gesture.state == UIGestureRecognizerStateEnded) {
        newYPoint = gesture.view.frame.origin.y+dY;
        if (gesture.view.frame.origin.x+dX<(self.view.frame.size.width/2)) {
            newXPoint = 0;
        }
        else {
            newXPoint = self.view.frame.size.width - gesture.view.frame.size.width;
//The below is just an attempt to remove and re-add constraints so the view will stick to the right side of the screen. It is not working :( 
            [self.view removeConstraint:[NSLayoutConstraint constraintWithItem:self.anotherView
                                                                  attribute:NSLayoutAttributeLeft
                                                                  relatedBy:NSLayoutRelationLessThanOrEqual
                                                                     toItem:self.view
                                                                  attribute:NSLayoutAttributeLeft
                                                                 multiplier:1.0
                                                                   constant:0]];

            [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.anotherView
                                                                  attribute:NSLayoutAttributeRight
                                                                  relatedBy:NSLayoutRelationLessThanOrEqual
                                                                     toItem:self.view
                                                                  attribute:NSLayoutAttributeRight
                                                                 multiplier:1.0
                                                                   constant:0]];


        }


            //        self.draggedViewCoordinate = gesture.view.frame.origin;

        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.70];
        [UIView setAnimationDelay:0.0];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        [self.anotherView layoutIfNeeded];
        [UIView commitAnimations];
        [self.tableView setScrollEnabled:YES];
    }

}

我不知道如何更新约束以使 View 保持在新的拖动位置。有人可以帮忙吗?

最佳答案

接受的答案不正确。 UI 添加/删除约束是非常昂贵的操作。 适当的解决方案将改变

self.yCoordinate.constant

self.xCoordinate.constant

基于 dX 和 dY 的属性。

关于ios - 动态/可拖动 UIView 的自动布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19398662/

有关ios - 动态/可拖动 UIView 的自动布局的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - nanoc 和多种布局 - 2

    是否可以为特定(或所有)项目使用多个布局?例如,我有几个项目,我想对其应用两种不同的布局。一个是绿色的,一个是蓝色的(但是)。我想将它们编译到我的输出目录中的两个不同文件夹中(例如v1和v2)。我一直在玩弄规则和编译block,但我不知道这是怎么回事。因为,每个项目在编译过程中只编译一次,我不能告诉nanoc第一次用layout1编译,第二次用layout2编译。我试过这样的东西,但它导致输出文件损坏。compile'*'doifitem.binary?#don’tfilterbinaryitemselsefilter:erblayout'layout1'layout'layout2'

  6. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - 在 Ruby 中动态创建数组 - 2

    有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.

  9. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  10. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

随机推荐