Вопрос

I am using the iCarousel Library and am having some problems.

In the Controls Demo Example Project, a XIB file is used and the view is setup like:

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
    if (!view)
    {
        //load new item view instance from nib
        //control events are bound to view controller in nib file
        //note that it is only safe to use the reusingView if we return the same nib for each
        //item view, if different items have different contents, ignore the reusingView value
        view = [[[NSBundle mainBundle] loadNibNamed:@"ItemView" owner:self options:nil] lastObject];
    }
    return view;
}

Because I am using Storyboards I create a View Controller and setup the view like this:

- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{

    NSString * storyboardName = @"MainStoryboard";
    NSString * viewControllerID = @"DuuinNewsItem";
    UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];

    //create new view if no view is available for recycling
    if (!view)
    {
        DUDuuin *tDuuin = [_duuins objectAtIndex:index];
        DUNewsItemViewController * controller = (DUNewsItemViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
        controller.duuin =  tDuuin;
        view = controller.view;
        [view setFrame:CGRectMake(0, 0, 314.0f, 415.0f)];

    }

    return view;
}

When I add an action to any button in the view I get the error:

enter image description here

I have tried a lot of things that are recommended in Stackoverflow, but I cannot find a solution:

I tried:

  • Setting the outlet to Strong (someone says it's a problem because ARC)
  • Deleting the sender in the action
  • Adding the method in the View Controller that have the icarousel

****UPDATE****

Now i see other issue. When i define the Action in the DUNewsItemViewController and try it in the simulator, it says :

-[__NSCFType btnTest:]: unrecognized selector sent to instance 0x1577c650

So, i adde the method in the .m file of the View Controller that have the iCarousel and the problem still the same:

EXC_BAD_ACCESS (code=2)

Some info:

  • I'm using ARC
  • It's on Storyboards
  • The number of views is dynamic
Это было полезно?

Решение

Your main issue here is not with the view specifically but rather with your DUNewsItemViewController instance. You create your controller in the method you have provided and return the view. The view is being retained by iCarousel. Your DUNewsItemViewController on the other hand is not. There is nothing that is strongly pointing to it. Since there are no strong pointers to it, it is being deallocated. Your view is displaying correctly, with all of your buttons, because again, it is being retained outside of your DUNewsItemViewController. When a button is pressed it attempts to access its action method and fails because the controller no longer exists.

To fix this issue you need to create a strong pointer to your controller (not the button as you attempted before). I am not recommending a perfect strategy, rather one that works.

You could create a mutable array (as a property) and add the viewcontrollers into it (if there are more than one) as you create them. This way the controller that is iCarousel's delegate/datasource holds a reference to it:

if (!view)
{
    DUDuuin *tDuuin = [_duuins objectAtIndex:index];
    DUNewsItemViewController * controller = (DUNewsItemViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
    // Add controller to array to hold a strong reference to it.
    [self.myMutableArray addObject:controller];
    //
    controller.duuin =  tDuuin;
    view = controller.view;
    [view setFrame:CGRectMake(0, 0, 314.0f, 415.0f)];

}

Otherwise, if there is only one (or a few) you could create unique outlets:

@property (strong, nonatomic) DUNewsItemViewController *firstVC; 

and in your carousel:viewForItemAtIndex:reusingView:view method include a line self.firstVC = controller.

If something does not make sense let me know. Again, there are probably better implementations but this should work. The reason that the XIBs worked in the example is because they are just UIViews not UIViewController subclasses like you are using. Again, your view is working like it should (displaying, just like the example), but your controller is being deallocaed (not like the example, since there is no controller being used).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top