jjzjj

Objective-C:(奇怪)UIButton 框架 NSLogs 不同的坐标与其显示(和接收触摸)的位置

coder 2024-01-27 原文

更新的解决方案:主要问题是我的速度计算返回一个整数 - 0 对于所有情况,除了索引 3 处的对象,它是 1 - 尽管被标记为实例化为 float。结果?这些按钮从起点到终点处于“无限”动画(速度为 0 的动画)中。

////////////////////////////////////

奇怪:我以编程方式在我的 View 上绘制一些按钮,在对我的代码进行故障排除时,我发现按钮的框架/位置/中心(在位置 A)与它们实际显示的位置不同(位置 B)。这是我第一次遇到这种现象..

(更糟糕的是,我正在使用 hitTest:withEvent: 并根据它们的框架返回按钮,所以我实际上是在跟踪位置 A 的点击(和触发 Action ),甚至尽管按钮本身显示在位置 B。)

注意事项和注意事项:其中一个按钮显示正确。我不知道为什么。所有按钮的动画效果都正确,因为动画超出了它们的框架。

我确定我的代码中遗漏了一些东西,但我已经研究了好几个小时,鉴于我的框架报告错误,我需要更多的眼睛!

图表:

+-----------------------+
|(mainV)                |
|                       |
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(sB)||
|                 +----+|
|                 +----+|
|                 |(dW)||
|                 +----+|
|+---------------------+|
||(mV)                 ||
|+---------------------+|
+-----------------------+

图例:

  • (mainV) = 主视图/ View Controller ,所有内容的父 View
  • (mV) = menuView, (mainV) 的 subview
  • (dW) = drawButton,(mV) 的 subview ,以及我构建其他按钮的“ anchor ”
  • (sB) = sizeButton 的实例,(mV) 的 subview ,使用 hitTest:withEvent: 获取父 View 框架之外的触摸

代码和注释:

中央按钮创建方法,我最初调用和创建按钮的地方,大多数变量都是实例变量

- (void)addSizeSubButtons {

    BOOL showAnimation = NO;

    if ([drawSizeButtonsArray count] == 0) {

        for (int i = 0; i < kNumberOfDrawSizes; i++) {

            // this method is defined below
            // short story is it makes 4 buttons and adds them to an array
            [self makeSizeButton];
        }

        showAnimation = YES;
    }

    // drawSizeButtonsArray is the array from before - see makeSizeButtons below
    for (UIButton *sizeButton in drawSizeButtonsArray) {

        int buttonIndex = [drawSizeButtonsArray indexOfObject:sizeButton];

        // drawButton is my unofficial anchor point - its center is {287.8, -24.25}
        // sizing code in general works and I don't believe is at play here
        // see (dW) in the diagram above..
        [sizeButton setFrame:CGRectMake(0,
                                        0,
                                        drawButton.bounds.size.height * kStackButtonRatio,
                                        drawButton.bounds.size.height * kStackButtonRatio)];

        CGPoint position = CGPointMake(drawButton.center.x,
                                       drawButton.center.y - sizeButton.bounds.size.height * (1.1 + buttonIndex));

        [sizeButton.layer setPosition:position];

        NSLog(@"sizeButton made at %@ named %@",NSStringFromCGPoint(sizeButton.center),sizeButton);

        // NSLog Output (all coords relative to (mV) from legend above:
        // sizeButton made at {287.8, -66.6} (this is loop #1/sizeButton atIndex:0)
        // sizeButton made at {287.8, -105.1} (this is loop #2/sizeButton atIndex:1)
        // sizeButton made at {287.8, -143.6} (this is loop #3/sizeButton atIndex:2)
        // sizeButton made at {287.8, -182.1} (this is loop #4/sizeButton atIndex:3)
        // note: I have tested that the buttons are all different/at different memory addresses
        // --------------------
        // HOWEVER, visual display locations are as follows:
        // button atIndex:0 @ {287.8, -24.25} (remember this is the same as drawButton!)
        // button atIndex:1 @ {287.8, -24.25} (also wrong, and also hidden behind drawButton)
        // button atIndex:2 @ {287.8, -24.25} (three in a row in the wrong place)
        // button atIndex:3 @ {287.8, -182.1} (!! HARK! this one is actually in the right place.. no clue why one is and the other three are not)

        [sizeButton.layer setCornerRadius:sizeButton.bounds.size.width / 7.5];
    }

    // animations are actually working as desired, because they run off the frame
    // as soon as the animation kicks off, buttons all appear in the right place
    // and take the correct action; still, i will include the core method just in case
    if (showAnimation == YES) {

        for (UIButton *sizeButton in drawSizeButtonsArray) {

            // so my button is moving FROM its anchor TO its actual center
            CGPoint origin = drawButton.center;
            CGPoint destination = sizeButton.center;

            // this is just to create a visual effect
            float speed = ( [drawSizeButtonsArray indexOfObject:sizeButton] + 1 ) / [drawSizeButtonsArray count];

            // my central animation method, included below
            CABasicAnimation *slideButton = [self slideButton:sizeButton
                                                    fromPoint:origin
                                                      toPoint:destination
                                                      atSpeed:speed];

            [sizeButton.layer addAnimation:slideButton
                                    forKey:@"slideSizeButtonAnimation"];
        }

    }
}

从上面调用的 Button Creator Helper/Worker 方法

- (void)makeSizeButton {

    UIButton *sizeButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [drawSizeButtonsArray addObject:sizeButton];

    // button presses
    [sizeButton setUserInteractionEnabled:YES];
    [sizeButton addTarget:self
                   action:@selector(drawSizeButtonPressed:)
         forControlEvents:UIControlEventTouchUpInside];

    // TO DO: remove these debug titles and replace with dots
    [sizeButton setTitle:[NSString stringWithFormat:@"%d",[drawSizeButtonsArray indexOfObject:sizeButton]]
                forState:UIControlStateNormal];
    [sizeButton setTitleColor:[UIColor blackColor]
                     forState:UIControlStateNormal];

    [sizeButton setBackgroundColor:[UIColor whiteColor]];

    // show it!
    [self addSubview:sizeButton];
    [self sendSubviewToBack:sizeButton];

}

动画助手方法

- (CABasicAnimation *)slideButton:(UIButton *)button
                        fromPoint:(CGPoint)origin
                          toPoint:(CGPoint)destination
                          atSpeed:(float)speed{

    // now show animation
    CABasicAnimation *slideAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    [slideAnimation setDelegate:self];

    // from & to values
    [slideAnimation setFromValue:[NSValue valueWithCGPoint:origin]];
    [slideAnimation setToValue:[NSValue valueWithCGPoint:destination]];

    // easing in and out.. oh yeah!
    [slideAnimation setDuration:kAnimationTiming / speed];
    CAMediaTimingFunction *easeInOut = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [slideAnimation setTimingFunction:easeInOut];

    NSLog(@"slide animation from %@ to %@",NSStringFromCGPoint(origin),NSStringFromCGPoint(destination));

    // NSLog Output: (all these values are correct/what I intended)
    // AND recall that all animations display properly!
    // in fact, judging by NSLog, everything is working fine.. but visually it is not
    // slide animation from {287.8, -24.25} to {287.8, -66.6} (for button atIndex:0)
    // slide animation from {287.8, -24.25} to {287.8, -105.1} (for button atIndex:1)
    // slide animation from {287.8, -24.25} to {287.8, -143.6} (for button atIndex:2)
    // slide animation from {287.8, -24.25} to {287.8, -182.1} (for button atIndex:3)

    return slideAnimation;
}

最佳答案

如果禁用动画,是否还会出现此问题?

您是否正在对任何 View 应用转换?

有一件事我要注意:设置 UIView 的框架然后调整其层的位置很奇怪。如何使用 [sizeButton setCenter:position] 而不是访问图层。我不认为这是问题所在,但它可能与它有关。同样,为什么不使用 UIView 的动画方法而不是潜入 CABasicAnimation 领域呢?

关于Objective-C:(奇怪)UIButton 框架 NSLogs 不同的坐标与其显示(和接收触摸)的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11805980/

有关Objective-C:(奇怪)UIButton 框架 NSLogs 不同的坐标与其显示(和接收触摸)的位置的更多相关文章

  1. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  2. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  3. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  4. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  5. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  6. ruby-on-rails - 如何用不同的用户运行nginx主进程 - 2

    A/ctohttp://wiki.nginx.org/CoreModule#usermaster进程曾经以root用户运行,是否可以以不同的用户运行nginxmaster进程? 最佳答案 只需以非root身份运行init脚本(即/etc/init.d/nginxstart),就可以用不同的用户运行nginxmaster进程。如果这真的是你想要做的,你将需要确保日志和pid目录(通常是/var/log/nginx&/var/run/nginx.pid)对该用户是可写的,并且您所有的listen调用都是针对大于1024的端口(因为绑定(

  7. ruby - 下载位置 Selenium-webdriver Cucumber Chrome - 2

    我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1

  8. ruby - 从 sinatra 中的 before do block 返回不同的值 - 2

    有没有办法在sinatra的beforedoblock中停止执行并返回不同的值?beforedo#codeishere#Iwouldliketo'return"Message"'#Iwouldlike"/home"tonotgetcalled.end//restofthecodeget'/home'doend 最佳答案 beforedohalt401,{'Content-Type'=>'text/plain'},'Message!'end如果你愿意,你可以只指定状态,这里有状态、标题和正文的例子

  9. ruby - Heroku production.log 文件位置 - 2

    我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc

  10. ruby-on-rails - Sunspot:如何对具有不同值的多个字段进行全文查询? - 2

    我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使

随机推荐