开发者

iPhone - Objective C - UIScrollView inside UITableView rendering funny

开发者 https://www.devze.com 2023-04-07 21:08 出处:网络
I\'m currently working on an iPhone app that\'s doing some strange things with a UIScrollView inside a UITableView.This is my first foray into iPhone dev, so I\'m sure it\'s something silly I\'m missi

I'm currently working on an iPhone app that's doing some strange things with a UIScrollView inside a UITableView. This is my first foray into iPhone dev, so I'm sure it's something silly I'm missing.

In each UITableViewCell I am putting in a basic UITableViewCell. In that UITableViewCell is a Label and a UIScrollView.

The label and scrollview is setup and working properly, but when it first displays it is offset about 30 pixels down on the y axis than it should be, or is positioned by the XIB/NIB. I am not moving it around manually. The label shows up in the right spot. at 0,0. The UIScrollView should be showing up at 0,22 but is showing up closer to 0,40.

When I swipe to scroll the containing UITableView, then all the UIScrollViews will show up in the right spot assuming that when the UITableView scrolled that UITableViewCell went offscreen.

Here is the code for the UITableView.cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  static NSString *CellIdentifier = @"GalleryRowCell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
  [cell.layer setMasksToBounds:TRUE];
  [cell.layer setCornerRadius:10.0];


  Contagion *c = (Contagion *)[self.dataSet objectAtIndex:indexPath.row];
  GalleryRowViewController *subView = [[GalleryRowViewController alloc] initWithContagion:c];
  [cell.contentView addSubview:subView.view];
  subView.contagionName.text = c.name;
  subView.contagion = c;
  return cell;
}

Here is the code for my GalleryRowViewController.viewDidLoad

- (void)viewDidLoad {

[super viewDidLoad];

self.imageScroll.delegate = self;

[self.imageScroll setBackgroundColor:[UIColor blackColor]];
[self.imageScroll setCanCancelContentTouches:NO];

self.imageScroll.indicatorStyle = UIScrollViewIndicatorStyleWhite;
self.imageScroll.clipsToBounds = NO;开发者_StackOverflow社区
self.imageScroll.scrollEnabled = YES;
self.imageScroll.pagingEnabled = NO;

NSInteger x = 0;
CGFloat xPos = 0;
for (x=0;x<=10;x++) {
  UIImage *image = [UIImage imageNamed:@"57-icon.png"];
  UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
  [imageView setBackgroundColor:[UIColor yellowColor]];

  CGRect rect = imageView.frame;
  rect.size.height = 70;
  rect.size.width = image.size.width;
  rect.origin.x = xPos;
  rect.origin.y = 5;

  imageView.frame = rect;

  [self.imageScroll addSubview:imageView];
  xPos += imageView.frame.size.width+5;
}

[self.imageScroll setContentSize:CGSizeMake(xPos, [self.imageScroll bounds].size.height)];

}

--- EDIT FOR IMAGES ---

After App Loads: http://img809.imageshack.us/img809/4576/screenshot20110927at427.png

After Scrolling the rows offscreen and back: http://img690.imageshack.us/img690/9461/screenshot20110927at428.png


Well, as my previous response was at too low a level, let me take another shot at it.

First, I just noticed the core problem that you're using a viewcontroller for each cell. To quote Apple, " "A single view controller typically manages the views associated with a single screen’s worth of content." That would also get rid of your XIB (just manually configuring your scrollview), which I bet will get rid of your problem.

To proceed, your main choice is whether to create a ContagionTableViewCell class or not as suggested by Scott.

If so, following the Elements example, create a subclass of UITableViewCell ContagionTableViewCell with properties of a scrollView, a labelview and a contagion. Like they use a custom setter for the element, use one for the contagion, so that whenever it is assigned, it also updates the cells label (and associated pictures).

Move your imageScroll code from GalleryRowViewController.viewDidLoad into the ContagionTableViewCell init code. Put the image code into a new routine, which will be called from the contagion setter.

If NOT, then move the GalleryRowView Controller code into your UITableView. I suggest you take a look at cellForRowAtIndexPath in Apple's tableViewSuite, the fourth example on subviews. In particular, it shows this pattern of separating the creation of a cell (when you need a brand new one) vs configuring the cell (when reusing it). As you have 10 imageViews inside your scrollView, you'll have to decide whether to delete all those (and/or the scrollview), or just reach inside and update their images when a cell is reused.


Can you post a screenshot. Its a bit hard to visualize what you are describing. I'm not sure how you are computing y origin to be 22.

As a side note I believe its cleaner to do this by creatint your own TableViewCell subclass and use that instead of the default UITableViewCell. There is an example called Elements which shows how to do this properly: http://developer.apple.com/library/ios/#samplecode/TheElements/Introduction/Intro.html


Well, I don't know it's the cause of your problem, but you've definitely got an issue. Note that every time you are asked for a cell, you're adding the galleryRow subview. When a cell goes off-screen, it's put on the reusableCell queue. Then you're asked for another cell; you get it from the queue, it still has the old galleryRow subview, and now you add another one; so that's not good. You should either reuse or delete the old one.

Finally, why are you using UITableViewCellStyleSubtitle, and then not using any of the default fields in that UITableView?

0

精彩评论

暂无评论...
验证码 换一张
取 消