我正在处理一个包含从自定义类构建的视图列表的scrollview。此类是具有图像和删除按钮以及委托的视图。当我按下删除按钮时,它调用委托函数(委托是scrollview,scrollview从数组中删除视图以删除它)。我遇到的问题是,当按下删除按钮时,该项目将被删除,但不会被删除,因此按钮和图像将保留在屏幕上。
我第一次使用ARC而且我有一种感觉我做错了什么。通常我可以使用保留和释放,我可以调试这个,但ARC对我来说感觉很神秘,而且我有点难过为什么视图没有得到dealloc'd。
这是我的代码:
VideoScrollView:
#import <UIKit/UIKit.h>
#import "VideoButtonView.h"
@interface VideoScrollView: UIScrollView <VideoButtonViewDelegate>
@property (retain, nonatomic) NSMutableArray *buttonArray;
- (void)setScrollViewContentSize: (CGSize) minimumSize;
- (void)buttonAdded: (UIImage*)image withMinimumSize: (CGSize) minimumSize;
- (void)respondToDelete:(id)sender;
@end
#import "VideoScrollView.h"
@implementation VideoScrollView
#define BUTTON_SIDE_LENGTH 60
#define BUTTON_BUFFER_LENGTH 10
#define INSET_HEIGHT 0
#define INSET_WIDTH 0
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.buttonArray = [[NSMutableArray alloc] init];
}
return self;
}
- (id)init
{
self = [super init];
if (self) {
// Initialization code
self.buttonArray = [[NSMutableArray alloc] init];
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
self.buttonArray = [[NSMutableArray alloc] init];
}
return self;
}
-(BOOL)touchesShouldCancelInContentView:(UIView *)view {
if([view class] == [UIButton class])
return true;
return [super touchesShouldCancelInContentView:view];
}
- (void)setScrollViewContentSize: (CGSize) minimumSize {
float scrollViewWidth = self.frame.size.width;
float buttons_per_row = scrollViewWidth / (BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH);
float num_rows = ceil([self.buttonArray count] / floorf( buttons_per_row ));
self.contentInset = UIEdgeInsetsMake(INSET_HEIGHT, INSET_WIDTH, INSET_HEIGHT, INSET_WIDTH);
CGFloat min_width = minimumSize.height - INSET_HEIGHT*2;
CGFloat acutal_width = (BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH) * num_rows + BUTTON_BUFFER_LENGTH;
CGFloat contentHeight = MAX(acutal_width, min_width);
CGSize temp_size = CGSizeMake(minimumSize.width, contentHeight);
self.contentSize = temp_size;
}
- (void)setButtonLocations {
float scrollViewWidth = self.frame.size.width;
float buttons_per_row = scrollViewWidth / (BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH);
//float num_rows = 0;
//num_rows = ceil([self.buttonArray count] / floorf( buttons_per_row ));
float offset = scrollViewWidth - (BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH)*buttons_per_row + BUTTON_BUFFER_LENGTH;
offset/=2;
int count = 0;
for(UIButton *button in self.buttonArray) {
CGFloat button_x = (CGFloat)(count % (int)buttons_per_row)*(BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH) + BUTTON_BUFFER_LENGTH + offset;
CGFloat button_y = (CGFloat)floorf(count / (int)buttons_per_row)*(BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH) + BUTTON_BUFFER_LENGTH;
button.frame = CGRectMake(button_x, button_y, BUTTON_SIDE_LENGTH, BUTTON_SIDE_LENGTH);
count++;
}
}
- (void)buttonAdded: (UIImage*)image withMinimumSize: (CGSize) minimumSize {
int scrollViewWidth = self.frame.size.width;
int buttons_per_row = scrollViewWidth / (BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH);
int button_count = [self.buttonArray count];
CGFloat button_x = (CGFloat)(button_count % buttons_per_row)*(BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH) + BUTTON_BUFFER_LENGTH;
CGFloat button_y = (CGFloat)floor(button_count / buttons_per_row)*(BUTTON_SIDE_LENGTH + BUTTON_BUFFER_LENGTH) + BUTTON_BUFFER_LENGTH;
VideoButtonView* temp_button_view = [[VideoButtonView alloc] initWithFrame:CGRectMake(button_x, button_y, BUTTON_SIDE_LENGTH, BUTTON_SIDE_LENGTH)];
temp_button_view.delegate = self;
[self addSubview:temp_button_view];
[self.buttonArray addObject:temp_button_view];
[self setScrollViewContentSize:minimumSize];
}
- (void)respondToDelete: (id)sender
{
[self.buttonArray removeObject:sender];
}
@end
VideoButtonView:
#import <UIKit/UIKit.h>
@protocol VideoButtonViewDelegate <NSObject>
- (void)respondToDelete: (id)sender;
@end
@interface VideoButtonView : UIView
@property (retain, nonatomic) UIButton *videoButton;
@property (retain, nonatomic) UIButton *deleteButton;
@property(nonatomic,assign)id<VideoButtonViewDelegate> delegate;
@end
#import "VideoButtonView.h"
#define DELETE_BUTTON_LENGTH 5
@implementation VideoButtonView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.videoButton = [[UIButton alloc] init];
[self.videoButton setBackgroundColor:[UIColor blueColor]];
self.deleteButton = [[UIButton alloc] init];
[self setFrame:frame];
[self.deleteButton addTarget:self action:@selector(deletePressed:) forControlEvents:UIControlEventTouchUpInside];
[self.deleteButton setBackgroundImage:[[UIImage imageNamed:@"delete_button.png"]
stretchableImageWithLeftCapWidth:8.0f
topCapHeight:0.0f]
forState:UIControlStateNormal];
[self.deleteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.deleteButton setTitle:@"Delete" forState:UIControlStateNormal];
self.deleteButton.titleLabel.font = [UIFont boldSystemFontOfSize:6];
self.deleteButton.titleLabel.shadowColor = [UIColor lightGrayColor];
self.deleteButton.titleLabel.shadowOffset = CGSizeMake(0, -1);
[self addSubview:self.videoButton];
[self addSubview:self.deleteButton];
[self bringSubviewToFront:self.deleteButton];
}
return self;
}
-(void)deletePressed: (id)sender {
if([self.delegate respondsToSelector:@selector(respondToDelete:)])
{
//send the delegate function with the amount entered by the user
[self.delegate respondToDelete:self];
}
}
-(void) setFrame:(CGRect)frame
{
[super setFrame:frame];
CGRect video_frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
[self.videoButton setFrame:video_frame];
[self.videoButton setBackgroundColor:[UIColor blueColor]];
CGFloat delete_y = frame.size.height - 15;
CGRect deleteFrame = CGRectMake(10, delete_y, 40, 10);
[self.deleteButton setFrame:deleteFrame];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end
答案 0 :(得分:3)
您的按钮数组只是保持对视图上按钮的引用。通过从数组中删除项目,您无法从数组中将其从视图中删除。你需要有这样的东西:
- (void)respondToDelete: (id)sender {
[sender removeFromSuperview];
[self.buttonArray removeObject:sender];
}
答案 1 :(得分:2)
致电时
[self addSubview:yourSubview]
你的子视图被添加到self中,并且一个强指针被添加到self.subviews。当你想删除subView时,你需要做的第一件事就是调用
[yourSubview removeFromSuperView]
然后,如果您还删除了任何其他指向子视图的强指针,那么将调用dealloc方法。