Pregunta

Tengo una aplicación que contiene una vista de desplazamiento con varias vistas de table. Cada TableView se carga desde otro ViewController. Está construido a partir de la aplicación de muestra de Pagecontrol de Apple. Mi objetivo es que funcione exactamente como la aplicación meteorológica de Apple.

Tengo todo funcionando bien. Todo el contenido se carga perfectamente y desplazando de lado a lado muestra todas las vistas de tabla adecuadas y sus datos relativos. Tengo un botón que, cuando se hace clic, abre otra vista que le permite editar cada artículo, al igual que la aplicación meteorológica donde puede agregar una nueva ciudad, eliminarla o moverla.

El problema que estoy teniendo es cómo actualizo la vista de desplazamiento cuando el usuario termina de editar el elementos. Imagine en la aplicación PageControl que puede eliminar la página 5 o mover la página 4 a la posición #1, etc.

No he pegado ningún código porque: 1) es el mismo código en la aplicación PageControl; 2) No he descubierto por dónde empezar. Ojalá alguien aquí pueda ayudarme.

Gracias.

Actualización: (3/5/2010 3:18 AM EST)

Ok, entonces he estado trabajando en esto por un tiempo. Pude llamar a un método en MainView para actualizar HE ScrollView. El código parece un poco torpe, ¡pero funciona! Realmente no me gusta el código porque termino usando una propiedad una vez, y no puedo configurarla nuevamente, porque recibo un error objc[10801]: FREED(id): message release sent to freed object=0x3f4a490. ¿Para mí parece que el objeto se ha lanzado? Si es así, no sé cómo, ya que solo lo libero en el dealloc. dealloc nunca se llama (puse un NSLog para verificar) para que no sé qué está pasando.

Código: El código inicial es el mismo código de la aplicación de muestra de PageControl de Apple:

- (void)viewDidLoad {
    [super viewDidLoad];
    appDel = (iBarryAppDelegate *)[[UIApplication sharedApplication] delegate];
    managedObjectContext = appDel.managedObjectContext;
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i < numberOfPages; i++)
    {
        [controllers addObject:[NSNull null]];
    }
    self.viewControllers = controllers;
    [controllers release];
    scrollView.pagingEnabled = YES;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * numberOfPages, scrollView.frame.size.height);
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.scrollsToTop = NO;
    scrollView.delegate = self;
    pageControl.numberOfPages = numberOfPages;
    pageControl.currentPage = 0;
    //I end up commenting out all the method calls to
    //[self loadScrollViewWithPage:xxx]; and load all the views at once.
    //I know I should be lazy-loading here , but Scrolling is much 
    //faster if I load them all at once, instead 
    //of when they are about to be viewed.
    for (unsigned i = 0; i < numberOfPages; i++)
    {
        [self loadScrollViewWithPage:i];
    }
}
- (void)loadMainController:(int)page
{
    MainViewController *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[MainViewController alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }
    if (nil == controller.view.superview)
    {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];
    }
}
- (void)loadScrollViewWithPage:(int)page
{
    if (page < 0) return;
    if (page >= numberOfPages) return;
    [self loadMainController:page];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
    if (pageControlUsed)
    {
        return;
    }
    CGFloat pageWidth = scrollView.frame.size.width;
    int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    pageControl.currentPage = page;
//  [self loadScrollViewWithPage:page - 1];
//  [self loadScrollViewWithPage:page];
//  [self loadScrollViewWithPage:page + 1];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender
{
    int page = pageControl.currentPage;
//  [self loadScrollViewWithPage:page - 1];
//  [self loadScrollViewWithPage:page];
//  [self loadScrollViewWithPage:page + 1];
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    [scrollView scrollRectToVisible:frame animated:YES];
    pageControlUsed = YES;
}

Entonces tengo mi código para actualizar El ScrollView. Lo que hago es eliminar todas las subvisiones y cargarlas nuevamente. Nunca tendré más de 13 subvistas, no estoy seguro de si eliminarlas todas y recrearlas es una buena o mala idea.

- (void)reloadDataNow
{
    for(UIView *subview in [scrollView subviews]) {
            [subview removeFromSuperview];
            NSLog(@"removed a suview");
    }
    [self loadData]; //this method fetches which data will be 
    //in the scrollView. It reloads the number of pages based 
    //on the return result and an NSMutableArray where I store 
    //data to pass to the views that will appear in the scrollView
    NSMutableArray *controllers = [[NSMutableArray alloc] init];
    for (unsigned i = 0; i < numberOfPages; i++)
    {
        [controllers addObject:[NSNull null]];
    }
    scrollView.pagingEnabled = YES;
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * numberOfPages, scrollView.frame.size.height);
    scrollView.showsHorizontalScrollIndicator = NO;
    scrollView.showsVerticalScrollIndicator = NO;
    scrollView.scrollsToTop = NO;
    scrollView.delegate = self;
    pageControl.numberOfPages = numberOfPages;
    pageControl.currentPage = 0;
    for (unsigned i = 0; i < numberOfPages; i++)
    {
        MainViewController *controller = [controllers objectAtIndex:i];
        if ((NSNull *)controller == [NSNull null])
        {
            controller = [[MainViewController alloc] initWithPageNumber:i team:[[favoritesArray objectAtIndex:i] teamR]];
            [controllers replaceObjectAtIndex:i withObject:controller];
            [controller release];
        }
        if (nil == controller.view.superview)
        {
            CGRect frame = scrollView.frame;
            frame.origin.x = frame.size.width * i;
            frame.origin.y = 0;
            controller.view.frame = frame;
            [scrollView addSubview:controller.view];
        }
    }
    //********************CRASH******************
    //Ideally, I think, the line below would replace the contents of
    //viewControllers with the new controllers. Here is where I get the 
    //"objc[10801]: FREED(id): message release sent to freed object=0x3f4a490" 
    //error. This line should probably be placed after [self loadData] or something,
    //but it crashes so I put but here to display better. I tried
    //adding self.viewControllers = nil; but I don't think that is 
    //the problem with the error message.
    self.viewControllers = controllers;
}

los reloadDataNow El método se llama desde una vista infantil donde uno puede agregar o eliminar elementos Para mostrar en el ScrollView.

¿Fue útil?

Solución

(He tenido el mismo problema, quería agregar UIImageView's a mi vista principal y actualizarlos así) Acabo de utilizar una matriz NSMutable de los ViewControllers que desea mostrar en la vista, luego agregué o reste de eso según sea necesario, y cada vez que agrega o restas de esa matriz, luego llame Un metod desde el interior de su vista principal que pasa por ScrollView y elimina cada vista de ScrollView, y luego agrega el ViewController apropiado a ScrollView. Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top