草庐IT

ios - 随机放置的 UILabel 旋转后尺寸错误

coder 2024-01-30 原文

有一个 UIVew 容器,用于随机生成、旋转并放置到该 View 中的多个 UILabel,如果我使用角度 0、90、180、270 看起来不错,但如果角度随机生成的标签看起来展开,这对我来说是个问题因为单词应该放置得非常近并且没有交集,所以生成器看起来是这样的:

- (void) generate:(UIView *)container
            words:(NSArray *)words
           colors:(NSArray *)colors
      minFontSize:(float)minSize
      maxFontSize:(float)maxSize
      rotateWords:(BOOL)rotate
    useAngleRange:(BOOL)useRange
{
    usingRange = useRange;
    for (int i = 0; i < [words count]; i++) {
        UILabel *word_l = [[UILabel alloc] init];
        word_l.font = [UIFont fontWithName:@"EuropeBold" size:[self getRandomNumberBetween:minSize to:(i < probableBigFontWords) ? maxSize : (maxSize / 3)]];
        [word_l setText:words[i]];
        [word_l setTextColor:colors[arc4random_uniform([colors count])]];
        [word_l setBackgroundColor:[UIColor clearColor]];
        [word_l sizeToFit];

        CGRect fr = CGRectMake(0,
                               0,
                               word_l.frame.size.width,
                               word_l.frame.size.height);
        word_l.frame = fr;
        word_l.center = CGPointMake([self getRandomNumberBetween:175 to:639], [self getRandomNumberBetween:175 to:375]);
        if (rotate) {
            int angleType = arc4random_uniform(2);
            if (useRange) {
                int angle = (angleType == 1) ? [self getRandomNumberBetween:0 to:90] : [self getRandomNumberBetween:270 to:360];
                [word_l setTransform:CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(angle))];
            } else {
                [word_l setTransform:CGAffineTransformMakeRotation((angleType == 1) ? DEGREES_TO_RADIANS(270) : DEGREES_TO_RADIANS(360))];
            }
        }
        [container addSubview:word_l];
        while ([self viewIntersectsWithAnotherView:container chosenView:word_l]) {
            viewPositionMovingStep++;
            [self placeItem:container :word_l];
        }
    }
}

- (void)placeItem:(UIView *)container :(UILabel *)word_l
{
    CGRect initFr = word_l.frame;
    for (int i = 1; i <= 8; i++) {
        CGRect f = word_l.frame;
        switch (i) {
            case 1:
                f.origin.x = f.origin.x + viewPositionMovingStep;
                break;
            case 2:
                f.origin.x = f.origin.x + viewPositionMovingStep;
                f.origin.y = f.origin.y + viewPositionMovingStep;
                break;
            case 3:
                f.origin.y = f.origin.y + viewPositionMovingStep;
                break;
            case 4:
                f.origin.x = f.origin.x - viewPositionMovingStep;
                f.origin.y = f.origin.y + viewPositionMovingStep;
                break;
            case 5:
                f.origin.x = f.origin.x - viewPositionMovingStep;
                break;
            case 6:
                f.origin.x = f.origin.x - viewPositionMovingStep;
                f.origin.y = f.origin.y - viewPositionMovingStep;
                break;
            case 7:
                f.origin.y = f.origin.y - viewPositionMovingStep;
                break;
            case 8:
                f.origin.x = f.origin.x + viewPositionMovingStep;
                f.origin.y = f.origin.y - viewPositionMovingStep;
                break;
            default:
                break;
        }
        word_l.frame = f;
        if ([self viewIntersectsWithAnotherView:container chosenView:word_l]) {
            word_l.frame = initFr;
        } else {
            viewPositionMovingStep = 0;
            return;
        }
    }
}

-(BOOL)viewIntersectsWithAnotherView:(UIView *)container chosenView:(UIView *)chosenView
{
    for(UIView *view in [container subviews]){
        if (![chosenView isEqual:view]){
            BOOL framePartiallyOut = !CGRectEqualToRect(CGRectIntersection(chosenView.superview.bounds, chosenView.frame), chosenView.frame);
            if (usingRange) {
                if([self view:chosenView intersectsWith:view] || framePartiallyOut){
                    return YES;
                }
            } else {
                if(CGRectIntersectsRect(chosenView.frame, view.frame) || framePartiallyOut){
                    return YES;
                }
            }
        }
    }
    return NO;
}

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
{
    CGPoint poly1[4];
    CGRect bounds1 = view1.bounds;
    poly1[0] = [view1 convertPoint:bounds1.origin toView:nil];
    poly1[1] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y) toView:nil];
    poly1[2] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y + bounds1.size.height) toView:nil];
    poly1[3] = [view1 convertPoint:CGPointMake(bounds1.origin.x, bounds1.origin.y + bounds1.size.height) toView:nil];

    CGPoint poly2[4];
    CGRect bounds2 = view2.bounds;
    poly2[0] = [view2 convertPoint:bounds2.origin toView:nil];
    poly2[1] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y) toView:nil];
    poly2[2] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y + bounds2.size.height) toView:nil];
    poly2[3] = [view2 convertPoint:CGPointMake(bounds2.origin.x, bounds2.origin.y + bounds2.size.height) toView:nil];

    CGPoint ctl2 = [view1 convertPoint:poly2[0] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, ctl2)){
        return YES;
    }
    CGPoint ctr2 = [view1 convertPoint:poly2[1] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, ctr2)){
        return YES;
    }
    CGPoint cbr2 = [view1 convertPoint:poly2[2] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, cbr2)){
        return YES;
    }
    CGPoint cbl2 = [view1 convertPoint:poly2[3] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, cbl2)){
        return YES;
    }
    CGPoint ctl1 = [view2 convertPoint:poly1[0] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, ctl1)){
        return YES;
    }
    CGPoint ctr1 = [view2 convertPoint:poly1[1] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, ctr1)){
        return YES;
    }
    CGPoint cbr1 = [view2 convertPoint:poly1[2] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, cbr1)){
        return YES;
    }
    CGPoint cbl1 = [view2 convertPoint:poly1[3] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, cbl1)){
        return YES;
    }
    return NO;
}

-(int)getRandomNumberBetween:(int)from to:(int)to
{
    return (int)from + arc4random() % (to-from+1);
}

这是正确放置标签的方式:

这个示例短词具有随机生成的角度(范围 270-360、0-90):

正如您所注意到的,那里没有显示文本,标签看起来展开了,并且交叉检查器在这种情况下不起作用,如果从 viewDidLoadviewDidApper 调用此检查器根本不起作用,我真的需要帮助,有什么想法吗? 谢谢!

最佳答案

调整大小的问题是这样解决的:

- (void)placeItem:(UIView *)container :(UILabel *)word_l
{
    CGPoint initPoint = word_l.center;
    for (int i = 1; i <= 8; i++) {
        switch (i) {
            case 1:
                word_l.center = CGPointMake(word_l.center.x + viewPositionMovingStep, word_l.center.y);
                break;
            case 2:
                word_l.center = CGPointMake(word_l.center.x + viewPositionMovingStep, word_l.center.y + viewPositionMovingStep);
                break;
            case 3:
                word_l.center = CGPointMake(word_l.center.x, word_l.center.y + viewPositionMovingStep);
                break;
            case 4:
                word_l.center = CGPointMake(word_l.center.x - viewPositionMovingStep, word_l.center.y + viewPositionMovingStep);
                break;
            case 5:
                word_l.center = CGPointMake(word_l.center.x - viewPositionMovingStep, word_l.center.y);
                break;
            case 6:
                word_l.center = CGPointMake(word_l.center.x - viewPositionMovingStep,  - viewPositionMovingStep);
                break;
            case 7:
                word_l.center = CGPointMake(word_l.center.x, word_l.center.y - viewPositionMovingStep);
                break;
            case 8:
                word_l.center = CGPointMake(word_l.center.x + viewPositionMovingStep, word_l.center.y - viewPositionMovingStep);
                break;
            default:
                break;
        }
        if ([self viewIntersectsWithAnotherView:container chosenView:word_l]) {
            word_l.center = initPoint;
        } else {
            viewPositionMovingStep = 0;
            return;
        }
    }
}

原因是: 使用 transform 属性时,您不能通过更改框架来更改位置,您必须使用 center 属性。

因此这部分已修复,但留下了与旋转 View 相交相关的问题,检查器无法正常工作,但在其他项目中单独测试它表现良好。

他在那里:

- (BOOL)view:(UIView *)view1 intersectsWith:(UIView *)view2
{
    CGPoint poly1[4];
    CGRect bounds1 = view1.bounds;
    poly1[0] = [view1 convertPoint:bounds1.origin toView:nil];
    poly1[1] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y) toView:nil];
    poly1[2] = [view1 convertPoint:CGPointMake(bounds1.origin.x + bounds1.size.width, bounds1.origin.y + bounds1.size.height) toView:nil];
    poly1[3] = [view1 convertPoint:CGPointMake(bounds1.origin.x, bounds1.origin.y + bounds1.size.height) toView:nil];

    CGPoint poly2[4];
    CGRect bounds2 = view2.bounds;
    poly2[0] = [view2 convertPoint:bounds2.origin toView:nil];
    poly2[1] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y) toView:nil];
    poly2[2] = [view2 convertPoint:CGPointMake(bounds2.origin.x + bounds2.size.width, bounds2.origin.y + bounds2.size.height) toView:nil];
    poly2[3] = [view2 convertPoint:CGPointMake(bounds2.origin.x, bounds2.origin.y + bounds2.size.height) toView:nil];

    CGPoint ctl2 = [view1 convertPoint:poly2[0] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, ctl2)){
        return YES;
    }
    CGPoint ctr2 = [view1 convertPoint:poly2[1] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, ctr2)){
        return YES;
    }
    CGPoint cbr2 = [view1 convertPoint:poly2[2] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, cbr2)){
        return YES;
    }
    CGPoint cbl2 = [view1 convertPoint:poly2[3] fromView:nil];
    if (CGRectContainsPoint(view1.bounds, cbl2)){
        return YES;
    }
    CGPoint ctl1 = [view2 convertPoint:poly1[0] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, ctl1)){
        return YES;
    }
    CGPoint ctr1 = [view2 convertPoint:poly1[1] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, ctr1)){
        return YES;
    }
    CGPoint cbr1 = [view2 convertPoint:poly1[2] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, cbr1)){
        return YES;
    }
    CGPoint cbl1 = [view2 convertPoint:poly1[3] fromView:nil];
    if (CGRectContainsPoint(view2.bounds, cbl1)){
        return YES;
    }
    return NO;
}

有人有想法吗?

关于ios - 随机放置的 UILabel 旋转后尺寸错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38989888/

有关ios - 随机放置的 UILabel 旋转后尺寸错误的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  3. ruby-on-rails - 使用 Rmagick 或 ImageMagick 在背景上放置标题 - 2

    我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植

  4. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  5. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  6. ruby-on-rails - 错误 : Error installing pg: ERROR: Failed to build gem native extension - 2

    我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby​​'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe

  7. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  8. 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返回它复制的字节数,但是当我还没有下

  9. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  10. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

随机推荐