0

I am doing the parallax effect by using category by doing :

    add and UIView into the uitableView (via category
    add addObserver:forKeyPath so that whenever tableview is moving, i will reframe the view above

Details are below UIScrollView+Parallax.h

    #import <UIKit/UIKit.h>

    @class ParallaxView;
    @interface UIScrollView (Parallax)

    @property (strong, nonatomic)   ParallaxView    *parallaxView;
    - (void) addParallaxViewWith:(UIView*)parallaxView;
    - (void) removeKVO;

    @end


    @interface ParallaxView : UIView

    @end

UIScrollView+Parallax.m

static char parallaxKey;
    @implementation UIScrollView (Parallax)
    @dynamic parallaxView;


    #pragma mark - Add parallax view to scrollView
    - (void) addParallaxViewWith:(ParallaxView*)pView {
        if ( !self.parallaxView) {

            [self addSubview:pView];
            [self setParallaxView:pView];
        }

    }

    #pragma mark - Set parallaxView + register parallaxView as an observer
    - (void) setParallaxView:(ParallaxView *)parallaxView {
        objc_setAssociatedObject(self, &parallaxKey, parallaxView, OBJC_ASSOCIATION_ASSIGN);
    /* THESE LINE ARE CRASHING THE APP */
    //    [self addObserver:self.parallaxView
    //           forKeyPath:@"contentOffset"
    //              options:NSKeyValueObservingOptionNew
    //              context:nil];
    }

    #pragma mark - Get parallaxView
    - (ParallaxView*) parallaxView {
        return (objc_getAssociatedObject(self, &parallaxKey));
    }
    #pragma mark - Remove 
    - (void)removeKVO {
            [self removeObserver:self.parallaxView forKeyPath:@"contentOffset"];
    }

    @end

    @implementation ParallaxView

    -(id)init
    {
        //load xib from main bundle and assign it to self
        self = [[[NSBundle mainBundle]loadNibNamed:@"Parallex"
                                             owner:self
                                           options:nil] objectAtIndex:0];

        return self;
    }

    -(id)initWithFrame:(CGRect)frame
    {
        self = [self init];
        [self setFrame:frame];

        return self;
    }

   ................

    @end

And I am adding parallax to the table by doing

ParallaxView *pView = [[ParallaxView alloc]initWithFrame:CGRectMake(0, 0, 320, 160)];

[self.tableView addParallaxViewWith:pView];

However, [self addObserver:forKeyPath:options:context:nil] keeps crashing the app without no clues at all. If I comments this line out and app is not crashing but parallex effect is not working.

Any ideas for this problematics. Please help. Thanks

tranvutuan
  • 6,089
  • 8
  • 47
  • 83

2 Answers2

0
@implementation ParallaxView

//Add Observe Method
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if([keyPath isEqualToString:@"contentOffset"]){
        NSLog(@"contentOffset:%@", [change objectForKey:NSKeyValueChangeNewKey]);
    }
}

@end

Try to replace

 objc_setAssociatedObject(self, &parallaxKey, parallaxView, OBJC_ASSOCIATION_ASSIGN);

with

//Change to OBJC_ASSOCIATION_RETAIN_NONATOMIC
objc_setAssociatedObject(self, &parallaxKey, parallaxView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

parallaxView should be a strong reference.

simalone
  • 2,768
  • 1
  • 15
  • 20
  • simalone:thanks for your help. Unfortunately, I have just gave it a try and still crashing.... – tranvutuan Mar 25 '14 at 04:14
  • I have try your code in a new test Project, And it works after edit somewhere, see my edited answer. And my init method just call super not from nib, if still crash, check the nib. – simalone Mar 25 '14 at 05:21
0

Problem in code

 -(id)initWithFrame:(CGRect)frame
    {
        self = [self init];
        [self setFrame:frame];

        return self;
    }

In above code self = [self init]; and [self setFrame:frame]; will go in recursion will give crash ,First fix this I guess it will solve your problem,It should be like this

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

and also loading View from nib using

self = [[[NSBundle mainBundle]loadNibNamed:@"Parallex"
                                             owner:self
                                           options:nil] objectAtIndex:0];

this code is really a bad idea. you can refer THIS for this task. Happy and clean coding...

jnix
  • 480
  • 3
  • 10