我有一个包含使用原型单元格的 UITableView 的视图。它包含一些我已连接到界面生成器中的子类 UITableViewCell 的标签。
当我单击一行时,我在情节提要中创建了一个到详细视图的转场。这个视图也可以通过另一个类的 segue 访问。
我的表格和详细视图使用导航控制器。
我的问题是,当我从表视图转换到详细视图并多次返回时,我注意到过了一段时间,从详细视图转换回表视图开始变得生涩。表格滚动也开始有点生涩。
我正在使用ARC。
如果有人能给我关于可能导致这种情况的提示,或者我应该用来调查它的工具,我将不胜感激。
我会记下我的一些源代码以防万一。如果还有什么我应该提供的,请告诉我。
表格视图是从远程服务填充的,但是在表格已经填充并且我不再调用该服务之后会出现问题。
表视图标题:
#import <UIKit/UIKit.h>
#import "SearchManager.h"
@interface SearchViewController : UIViewController <UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource, FreeTextSearchClient>
@property (nonatomic, retain) IBOutlet UITableView *TableView;
@end
表格视图代码:
#import "SearchViewController.h"
#import "SearchManager.h"
#import "LocationTableViewCell.h"
#import "StarRatingDisplay.h"
#import "LocationViewController.h"
@interface SearchViewController ()
@end
@implementation SearchViewController
@synthesize TableView;
SearchManager *searchManager;
NSArray *locations;
bool isSearching = false;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
//hide nav bar
[self.navigationController setNavigationBarHidden:true];
//deselect cell
NSIndexPath *selectedPath = [self.TableView indexPathForSelectedRow];
[self.TableView deselectRowAtIndexPath:selectedPath animated:false];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
searchManager = [[SearchManager alloc] initWithFreeTextClient:self];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"LocationDetails"])
{
// Get reference to the destination view controller
LocationViewController *vc = [segue destinationViewController];
NSIndexPath *indexPath = [self.TableView indexPathForSelectedRow];
vc.location = [locations objectAtIndex:indexPath.row];
}
}
- (void)showStarRating:(LocationTableViewCell*) cell: (float) score {
int x = cell.titleLabel.frame.origin.x;
int y = cell.ratingLabel.frame.origin.y + 2;
//add rating
NSArray *stars = [StarRatingDisplay GetTinyStarsForScore:score];
NSEnumerator *enumerator = [stars objectEnumerator];
UIImage *thisStar;
int i = 0;
//create image views for stars and place them on the callout
while(thisStar = [enumerator nextObject]) {
UIImageView *view = [[UIImageView alloc] initWithImage:thisStar];
view.frame = CGRectMake(x+(thisStar.size.width + 2)*i, y, thisStar.size.width, thisStar.size.height);
[cell.contentView addSubview:view];
i++;
}
}
#pragma mark - UITableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if([locations count] == 0 && isSearching) {
return 1;
}
else {
return [locations count];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([locations count] == 0) {
return 53;
} else {
return 77;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([locations count] > 0) {
LocationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LocationCell"];
Location *location = [locations objectAtIndex:indexPath.row];
cell.titleLabel.text = location.Name;
cell.addressLabel.text = location.Address.description;
cell.ratingLabel.text = [NSString stringWithFormat:@"%d rating%@", location.Ratings, (location.Ratings != 1 ? @"s" : @"")];
[self showStarRating:cell :location.Score];
return cell;
}
else {
//if there are no locations, show the no results cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"NoResults"];
return cell;
}
}
#pragma mark - UISearchBarDelegate
- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar {
if(searchBar.text.length > 0) {
[searchManager FreeTextSearch:searchBar.text];
[searchBar resignFirstResponder];
isSearching = true;
}
}
- (void) searchBarCancelButtonClicked:(UISearchBar *)searchBar {
//clear search and remove keyboard
searchBar.text = @"";
[searchBar resignFirstResponder];
isSearching = false;
}
#pragma mark - SearchClient delegate
- (void) ReceiveTextSearchResponse:(NSArray *) response {
NSLog(@"Response received");
locations = response;
[self.TableView reloadData];
}
@end
表格单元格标题:
#import <UIKit/UIKit.h>
@protocol RatingTableViewDelegate <NSObject>
@required
- (void) changeCommentCellHeight:(int) height;
- (void) setEditingOffset;
- (void) removeEditingOffset;
@end
表格单元格:
@interface RatingTableCellViewController : UITableViewCell <UITextViewDelegate>
@property (nonatomic, unsafe_unretained) id <RatingTableViewDelegate> tableViewDelegate;
@property (nonatomic, assign) bool hasRating;
@property (nonatomic, assign) float rating;
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) IBOutlet UILabel *yourRatingLabel;
@property (nonatomic, retain) IBOutlet UITextView *textView;
@property (nonatomic, retain) IBOutlet UIImageView *star1;
@property (nonatomic, retain) IBOutlet UIImageView *star2;
@property (nonatomic, retain) IBOutlet UIImageView *star3;
@property (nonatomic, retain) IBOutlet UIImageView *star4;
@property (nonatomic, retain) IBOutlet UIImageView *star5;
- (IBAction) submitClicked:(id)sender;
- (IBAction) cancelClicked:(id)sender;
- (void) openCell;
- (void) closeCell;
- (void) cancelRating;
@end
详细视图标题:
#import <UIKit/UIKit.h>
#import "Location.h"
#import "RatingTableCellViewController.h"
@interface LocationViewController : UITableViewController <RatingTableViewDelegate>
@property (retain, nonatomic) Location *location;
@property (retain, nonatomic) IBOutlet UITableViewCell *averageRatingCell;
@property (retain, nonatomic) IBOutlet RatingTableCellViewController *yourRatingCell;
@property (retain, nonatomic) IBOutlet UILabel *ratingLabel;
@property (retain, nonatomic) IBOutlet UILabel *address;
@end
详细视图:
#import "LocationViewController.h"
#import "StarRatingDisplay.h"
#import "RatingViewController.h"
#import "RatingTableCellViewController.h"
@interface LocationViewController ()
@end
@implementation LocationViewController
@synthesize location;
@synthesize averageRatingCell, yourRatingCell;
@synthesize ratingLabel;
@synthesize address;
int commentCellHeight = 45;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[self showStarRating:averageRatingCell];
ratingLabel.Text = [NSString stringWithFormat: @"%d Rating%@:", location.Ratings, location.Ratings != 1 ? @"s" : @""];
self.navigationItem.title = location.Name;
address.text = location.Address.description;
address.lineBreakMode = UILineBreakModeWordWrap;
address.numberOfLines = 5;
yourRatingCell.tableViewDelegate = self;
// Show the nav bar. It might be hidden if coming from search view.
[self.navigationController setNavigationBarHidden:false];
}
- (void) setEditingOffset {
[self.tableView setContentOffset:CGPointMake(0, 60)];
}
- (void) removeEditingOffset {
[self.tableView setContentOffset:CGPointMake(0, 0)];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 1) {
return commentCellHeight;
}
else if(indexPath.section == 1 && indexPath.row == 0) {
return 70;
}
return 45;
}
- (void) changeCommentCellHeight:(int) height {
commentCellHeight = height;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (void)showStarRating:(UITableViewCell*) cell {
int x = 132;
int y = 12;
//add rating
NSArray *stars = [StarRatingDisplay GetStarsForScore:location.Score];
NSEnumerator *enumerator = [stars objectEnumerator];
UIImage *thisStar;
int i = 0;
//create image views for stars and place them on the callout
while(thisStar = [enumerator nextObject]) {
UIImageView *view = [[UIImageView alloc] initWithImage:thisStar];
view.frame = CGRectMake(x+(thisStar.size.width + 2)*i, y, thisStar.size.width, thisStar.size.height);
[cell.contentView addSubview:view];
i++;
}
}
- (void) viewWillDisappear:(BOOL)animated {
//reset the comment/rating cell height
NSIndexPath *commentPath = [NSIndexPath indexPathForRow:1 inSection: 0];
RatingTableCellViewController *ratingCell = (RatingTableCellViewController*)[self.tableView cellForRowAtIndexPath:commentPath];
[ratingCell cancelRating];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end