Обновление контента в представление ScrollView
У меня есть приложение, которое содержит scrollview с несколькими TableView. Каждый tableview загружается с другого viewcontroller. Он построен из примера приложения PageControl от Apple. Моя цель-заставить его работать точно так же, как приложение Apple weather.
У меня все работает просто отлично. Все содержимое загружается идеально и прокрутка из стороны в сторону отображает все правильные табличные представления и их относительные данные. У меня есть кнопка, которая при нажатии на нее открывает другой вид, который позволяет редактировать каждый элемент , как и приложение weather, в котором вы можете добавить новый город, удалить его или переместить.
Проблема, с которой я сталкиваюсь, заключается в том, как обновить scrollview, когда пользователь закончил редактирование элементов . Представьте, что в приложении PageControl можно удалить страницу 5 или переместить страницу 4 в позицию #1 и т. д.
Я не вставил никакого кода, потому что: 1) это тот же код в приложении PageControl; 2) я не понял, с чего начать. Надеюсь, кто-то здесь сможет помочь мне.
Спасибо.
ОБНОВЛЕНИЕ: (3/5/2010 3: 18 УТРА ПО ВОСТОЧНОМУ ВРЕМЕНИ)
Хорошо, я работаю над этим уже некоторое время. Я смог вызвать метод в mainView, чтобы обновить его scrollView. Код кажется довольно неуклюжим, но он работает! Мне действительно не нравится код, потому что я в конечном итоге использую свойство один раз, и я не могу установить его снова, потому что я получаю ошибкуobjc[10801]: FREED(id): message release sent to freed object=0x3f4a490
. Мне кажется, что объект был освобожден? Если да, то я не знаю, как, так как я только выпускаю его в dealloc
. dealloc
никогда не бывает позвонил (я поставил NSLog
, чтобы проверить), поэтому я не знаю, что происходит.
Код: исходный код-это тот же код из примера приложения PageControl от 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;
}
Затем у меня есть мой код, чтобы обновить скроллвью. Что я делаю, так это удаляю все подвиды и загружаю их снова. У меня никогда не будет больше 13 подвидов, не уверен, что удаление их всех и воссоздание их-хорошая или плохая идея.
- (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;
}
Метод reloadDataNow
вызывается из дочернего представления, в котором можно добавить или удалите элементы , чтобы отобразить их в scrollView.
1 ответ:
(у меня была та же проблема, я хотел добавить
UIImageView
в мой mainView и обновить их таким образом) я просто использовал NSMutable массив ViewControllers, которые вы хотите отобразить в представлении, затем добавить или вычесть из него по мере необходимости, и каждый раз, когда вы добавляете или вычитаете из этого массива, затем вызываете метод из вашего mainView, который проходит через scrollView и удаляет все представления из scrollView, а затем добавляет соответствующий viewController в scrollView. Надеюсь, это поможет.