1

i'am searching for a way to add a Subview (in my example a UIPickerView) to a ViewController like MBProgressHUD. My Subview is an UIView which has a UIPickerView and a UIButton on it to select an item.

I use this view in different ViewControllers, so it would be nice to encapsulate it in a own Class. My Problem is that it only works without ARC. With ARC the App crash with EXC_BAD_ACCESS CODE = 1.... So i think i have to set the variables to strong. Can anyone help me?!

The .h File looks as the following:

#

import <Foundation/Foundation.h>

typedef void(^completition)(NSString *result);

@interface CDPickerView : NSObject<UIPickerViewDataSource, UIPickerViewDelegate>

@property(nonatomic, strong) __block UIView *_view;
@property(nonatomic, strong) __block NSMutableArray *_selection;

-(void)addPickerToView:(UIView*)view withSelection:(NSMutableArray*)selection andReturnSelectedUsingBlock:(completition) compBlock;

@end

The .m File:

#import "CDPickerView.h"

@interface CDPickerView (){
//    __strong UIView *_view;
//    __strong NSMutableArray *_selection;
    __strong void (^completitionTest)(NSString* result);
}

@end

@implementation CDPickerView


-(id)init{

    if(!self){
        self = [self init];
    }
    return self;
}

-(void)addPickerToView:(UIView *)view withSelection:(NSMutableArray *)selection andReturnSelectedUsingBlock:(completition) compblock{
    self._view = view;
    self._selection = [[NSMutableArray alloc] initWithArray:selection];
    completitionTest = compblock;

    dispatch_async(dispatch_get_main_queue(), ^(void){
             [self addSelectionView];
    });


}

-(void)addPickerToView:(UIView *)view withSelection:(NSMutableArray *)selection{
    __view = view;
    __selection = [[NSMutableArray alloc] initWithArray:selection];
    dispatch_async(dispatch_get_main_queue(), ^(void){
        [self addSelectionView];
    });

}

-(void)addSelectionView{

    __strong UIView *custView = [[UIView alloc]initWithFrame:CGRectMake(5, 5, 310, 300)];
    custView.layer.cornerRadius = 10.0;
    custView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.90];
    __strong UIPickerView *picker = [[UIPickerView alloc]initWithFrame:CGRectMake(5, 5, 290, 200)];
    picker.dataSource = self;
    picker.delegate = self;
    [custView addSubview:picker];
    __strong UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 210, 310, 40)];
    [button setTitle:@"Auswählen" forState:UIControlStateNormal];
  //  button.frame =
    button.backgroundColor = [UIColor whiteColor];
    button.titleLabel.font = [UIFont systemFontOfSize:20.0];
    button.titleLabel.textColor = [UIColor blackColor];
    [button addTarget:self action:@selector(choiceButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    [custView addSubview:button];
    [__view addSubview:custView];
    [picker reloadAllComponents];

}

-(void)choiceButtonTapped{
    UIView *view = [[__view subviews] lastObject];
    UIPickerView *picker = [[view subviews] objectAtIndex:0];
    NSString *result = [__selection objectAtIndex:[picker selectedRowInComponent:0]];
    completitionTest(result);
    [view removeFromSuperview];


}


-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{

    return [__selection objectAtIndex:row];
}


-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{

    return __selection.count;
}

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
    return 1;
}



@end

To add this view i do the following:

  __strong NSMutableArray *selection = [[NSMutableArray alloc]initWithObjects:@"Test1",@"Test2",@"Test3",@"Test4", nil];

    __strong CDPickerView *picker = [[CDPickerView alloc]init];
    [picker addPickerToView:self.view withSelection:selection andReturnSelectedUsingBlock:^(NSString *result) {
        NSLog(@"Test: %@",result);
    }];

Thank for your help!

Gulliva
  • 488
  • 2
  • 10
  • First of all, `__block` can ONLY be used on local variables. Not instance variables, not properties, not parameters or return types. – newacct Feb 22 '14 at 04:28

1 Answers1

0

First of all it seems that you should read where __strong and __block should be user. Change

@property(nonatomic, strong) __block UIView *_view;
@property(nonatomic, strong) __block NSMutableArray *_selection;

to

@property(nonatomic, strong) UIView *_view;
@property(nonatomic, strong) NSMutableArray *_selection;

and

completitionTest = compblock;

to

completitionTest = [compblock copy];

in -(void)addPickerToView:(UIView *)view withSelection:(NSMutableArray *)selection

Avt
  • 16,927
  • 4
  • 52
  • 72
  • Was this answer helpful? – Avt Feb 21 '14 at 11:00
  • Sorry but this doesn't fix the problem... The completitionTest is like a Functionpointer.... With Copy the app crash the same way like before... I think some variables are to weak... Without ARC the Code works fine... And to change the property, i also tried before, this also doesn't work. – Gulliva Feb 22 '14 at 12:35
  • This answer makes no difference to the code. Adding `__block` to a non-local variable has no effect, so that can't fix anything. In ARC, assigning to a strong variable of block type copies it anyway, so adding another copy can't make a difference. – newacct May 26 '14 at 05:31