gpt4 book ai didi

iOS - 删除所有 subview 后重新添加 subview

转载 作者:行者123 更新时间:2023-11-29 00:28:59 28 4
gpt4 key购买 nike

我正在制作一个球程序,您可以通过长按手势将球 UIView subview 添加到 super View 。点击 View 会将其从父 View 中移除。

添加所有 View 效果很好,重新添加 View 效果很好,只要父 View 中至少有一个 View 。但是,一旦删除所有 subview ,长按应该会再次重新添加第一个 subview ,但程序会关闭。

我在其中一个线程中只收到一条释放消息,让我相信这是一个分配/释放问题,但 ARC 禁止我明确释放 View ,我相信 [removeFromSuperview] 会无论如何。

我不确定我错过了什么。感兴趣的特定方法是 tapped:createBall after tapped: has been used on all subviews.

ViewController.m

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, strong) UILongPressGestureRecognizer *longPressRecog;
@property (nonatomic, strong) UIPanGestureRecognizer *panRecog;
@property (nonatomic, strong) UITapGestureRecognizer *tapRecog;
@property (nonatomic, strong) UIDynamicAnimator *anim;
@property (nonatomic, strong) NSTimer* timer;
@property (nonatomic, strong) UIView *orangeBall, *blueBall;
@property (nonatomic) CGPoint ballCenter;
@property (nonatomic, strong) NSMutableArray* ballsArray;
@property (nonatomic, assign) CGRect originalBounds;

@property (nonatomic) UIAttachmentBehavior *attachmentBehavior;
@property (nonatomic) UIPushBehavior *pushBehavior;
@property (nonatomic) UIDynamicItemBehavior *ballPhysics;
@property (nonatomic) UICollisionBehavior *collisionBehavior;

-(void)physics;
-(void)createBall;

@end

@implementation ViewController


- (void)viewDidLoad {
[super viewDidLoad];

// Prepare to handle Long Press to create ball object
self.longPressRecog = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
self.longPressRecog.minimumPressDuration = 0.8f;
[self.longPressRecog setDelegate:self];

[self.view addGestureRecognizer:self.longPressRecog];
}

// Handles Long Presses and creates a ball within the view
- (void)longPress:(UILongPressGestureRecognizer *)sender {
if ([sender isEqual:self.longPressRecog]) {
if (sender.state == UIGestureRecognizerStateEnded) {
[self createBall];
}
}
}

// Set Ball Attributes
- (void)setOrangeBall {
if (self.viewLoaded) {
// Load ball view to screen
self.orangeBall = [[UIView alloc] initWithFrame:CGRectMake(100.0, 100.0, 50.0, 50.0)];
self.orangeBall.layer.cornerRadius = 25.0;
self.orangeBall.backgroundColor = [UIColor orangeColor];
self.orangeBall.layer.borderColor = [UIColor orangeColor].CGColor;
self.orangeBall.layer.borderWidth = 0.0;
[self.view addSubview:self.orangeBall];
} else {

}
}

- (void)setBlueBall {
// Load ball view to screen
self.blueBall = [[UIView alloc] initWithFrame:CGRectMake(160.0, 160.0, 50.0, 50.0)];
self.blueBall.layer.cornerRadius = 25.0;
self.blueBall.backgroundColor = [UIColor blueColor];
self.blueBall.layer.borderColor = [UIColor blueColor].CGColor;
self.blueBall.layer.borderWidth = 0.0;
[self.view addSubview:self.blueBall];
}


// Create Balls
- (void)createBall {
if (![_orangeBall superview] && ![_blueBall superview]) {
[self setOrangeBall];
} else if ([_orangeBall superview] && ![_blueBall superview]) {
[self setBlueBall];
} else {
// NOTHING
}

// Begin animations
self.anim = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

// Init Physics
[self physics];
}

// Gravity
- (void)physics {

//Add ball objects to NSMutableArray. Needed in order to add behaviors to all ball objects.
self.ballsArray = [NSMutableArray arrayWithObjects:self.orangeBall, self.blueBall, nil];

//Tapping Behavior
_tapRecog.delegate = self;
for (UIView *ball in _ballsArray) {
ball.userInteractionEnabled = YES;
_tapRecog = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[_tapRecog setNumberOfTapsRequired:2];
[ball addGestureRecognizer:_tapRecog];
}
}

- (void)tapped:(UITapGestureRecognizer *)recognizer {
//Delete tapped ball
[recognizer.view willRemoveSubview:recognizer.view];
[recognizer.view removeFromSuperview];
}


@end

以下是我能从线程错误中真正找到的所有内容:

UIKit`UIApplicationMain:
0x10acd4bc9 <+0>: pushq %rbp
0x10acd4bca <+1>: movq %rsp, %rbp
0x10acd4bcd <+4>: pushq %r15
0x10acd4bcf <+6>: pushq %r14
0x10acd4bd1 <+8>: pushq %r13
0x10acd4bd3 <+10>: pushq %r12
0x10acd4bd5 <+12>: pushq %rbx
0x10acd4bd6 <+13>: pushq %rax
0x10acd4bd7 <+14>: movq %rcx, %rbx
0x10acd4bda <+17>: movq %rsi, -0x30(%rbp)
0x10acd4bde <+21>: movl %edi, %r12d
0x10acd4be1 <+24>: movq 0xe7f7b8(%rip), %r13 ; (void *)0x0000000109c12cb0: objc_retain
0x10acd4be8 <+31>: movq %rdx, %rdi
0x10acd4beb <+34>: callq *%r13
0x10acd4bee <+37>: movq %rax, %r14
0x10acd4bf1 <+40>: movq %rbx, %rdi
0x10acd4bf4 <+43>: callq *%r13
0x10acd4bf7 <+46>: movq %rax, %r15
0x10acd4bfa <+49>: leaq 0x11dab6b(%rip), %r13 ; _UIApplicationLinkedOnVersion
0x10acd4c01 <+56>: movl (%r13), %eax
0x10acd4c05 <+60>: testl %eax, %eax
0x10acd4c07 <+62>: jne 0x10acd4c17 ; <+78>
0x10acd4c09 <+64>: cmpq $-0x1, 0x11d4ab7(%rip) ; WebKitSetIsClassic + 7
0x10acd4c11 <+72>: jne 0x10acd4c8a ; <+193>
0x10acd4c13 <+74>: movl (%r13), %eax
0x10acd4c17 <+78>: cmpl $0x20100, %eax ; imm = 0x20100
0x10acd4c1c <+83>: jb 0x10acd4c42 ; <+121>
0x10acd4c1e <+85>: callq 0x10b8f8a8a ; symbol stub for: objc_autoreleasePoolPush
0x10acd4c23 <+90>: movq %rax, %r13
0x10acd4c26 <+93>: movl %r12d, %edi
0x10acd4c29 <+96>: movq -0x30(%rbp), %rsi
0x10acd4c2d <+100>: movq %r14, %rdx
0x10acd4c30 <+103>: movq %r15, %rcx
0x10acd4c33 <+106>: callq 0x10acd4ca2 ; _UIApplicationMainPreparations
0x10acd4c38 <+111>: movq %r13, %rdi
0x10acd4c3b <+114>: callq 0x10b8f8a84 ; symbol stub for: objc_autoreleasePoolPop
0x10acd4c40 <+119>: jmp 0x10acd4c54 ; <+139>
0x10acd4c42 <+121>: movl %r12d, %edi
0x10acd4c45 <+124>: movq -0x30(%rbp), %rsi
0x10acd4c49 <+128>: movq %r14, %rdx
0x10acd4c4c <+131>: movq %r15, %rcx
0x10acd4c4f <+134>: callq 0x10acd4ca2 ; _UIApplicationMainPreparations
0x10acd4c54 <+139>: movq 0x11daa55(%rip), %rdi ; UIApp
0x10acd4c5b <+146>: movq 0x11489d6(%rip), %rsi ; "_run"
0x10acd4c62 <+153>: callq *0xe7f728(%rip) ; (void *)0x0000000109c15ac0: objc_msgSend
0x10acd4c68 <+159>: movq 0xe7f729(%rip), %rbx ; (void *)0x0000000109c12d20: objc_release
0x10acd4c6f <+166>: movq %r15, %rdi
0x10acd4c72 <+169>: callq *%rbx
0x10acd4c74 <+171>: movq %r14, %rdi
0x10acd4c77 <+174>: callq *%rbx
0x10acd4c79 <+176>: xorl %eax, %eax
0x10acd4c7b <+178>: addq $0x8, %rsp
0x10acd4c7f <+182>: popq %rbx
0x10acd4c80 <+183>: popq %r12
0x10acd4c82 <+185>: popq %r13
0x10acd4c84 <+187>: popq %r14
0x10acd4c86 <+189>: popq %r15
0x10acd4c88 <+191>: popq %rbp
0x10acd4c89 <+192>: retq
0x10acd4c8a <+193>: leaq 0x11d4a37(%rip), %rdi ; _UIApplicationLinkedOnVersionOnce
0x10acd4c91 <+200>: leaq 0xe82d08(%rip), %rsi ; __block_literal_global.1554
0x10acd4c98 <+207>: callq 0x10b8f92d6 ; symbol stub for: dispatch_once
0x10acd4c9d <+212>: jmp 0x10acd4c13 ; <+74>

最佳答案

当您双击“球”时,您将从其 super View 中删除该 View :

- (void)tapped:(UITapGestureRecognizer *)recognizer {
//Delete tapped ball
[recognizer.view willRemoveSubview:recognizer.view];
[recognizer.view removeFromSuperview];
}

但是,那个“球”仍然存在。下一次长按时,您的代码将跳过创建球(因为它们都存在),但在球创建方法中,您可以将它们添加到主视图中。当您的代码进入物理方法时,您尝试将碰撞行为添加到不在层次结构中的 View 中。

当您从 super View 中删除“球”时,您应该删除它们(将它们设置为 nil),或者下次将它们重新添加为 subview 。

这是一种方法,尽管不是最好的......

- (void)tapped:(UITapGestureRecognizer *)recognizer {
//Delete tapped ball
[recognizer.view willRemoveSubview:recognizer.view];
[recognizer.view removeFromSuperview];

if (recognizer.view == _blueBall) {
_blueBall = nil;
} else if (recognizer.view == _orangeBall) {
_orangeBall = nil;
}
}

关于iOS - 删除所有 subview 后重新添加 subview ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42374388/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com