Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITABLEView重复行问题_Ios_Objective C_Uitableview - Fatal编程技术网

Ios UITABLEView重复行问题

Ios UITABLEView重复行问题,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我无法解决此问题,也不知道为什么每次单击segment控件时,UITableView都会复制行。当段控件更改时,我想用新数据刷新表视图。我尝试了很多东西,在谷歌上搜索了一下,但找不到任何解决办法。如果有人能帮助我,我将不胜感激。我还在学习xcode,还有很多东西要学。这是我的密码- #import "citsViewController.h" #import "citsParseOperation.h" #import "citsFuelFinder.h" #import "citsTableV

我无法解决此问题,也不知道为什么每次单击segment控件时,UITableView都会复制行。当段控件更改时,我想用新数据刷新表视图。我尝试了很多东西,在谷歌上搜索了一下,但找不到任何解决办法。如果有人能帮助我,我将不胜感激。我还在学习xcode,还有很多东西要学。这是我的密码-

#import "citsViewController.h"
#import "citsParseOperation.h"
#import "citsFuelFinder.h"
#import "citsTableViewCell.h"
#import "citsAboutViewController.h"
#import "MBProgressHUD.h"
#import <CoreLocation/CoreLocation.h>

// this framework is imported so we can use the kCFURLErrorNotConnectedToInternet error code
#import <CFNetwork/CFNetwork.h>
#import <MapKit/MapKit.h>

@interface citsViewController ()
{
    CLLocationManager *locationManager;
    CLGeocoder *geocoder;
    CLPlacemark *placemark;
    NSString *currentLoc;
    int productName;

}

@property (nonatomic) NSMutableArray *earthquakeList;
@property (nonatomic) citsFuelFinder *currentEarthquakeObject;
@property (nonatomic, weak) IBOutlet UILabel *locationLabel;

// queue that manages our NSOperation for parsing earthquake data
@property (nonatomic) NSOperationQueue *parseQueue;

@end


#pragma mark -

@implementation citsViewController
@synthesize nomatchesView;
@synthesize footerLabel;
@synthesize headerLabel;
@synthesize fuelType;
@synthesize bannerIsVisible;

- (void)viewDidLoad {

    [super viewDidLoad];


    //refresh the tableview
    UIRefreshControl *refreshControl=[[UIRefreshControl alloc] init];

    [refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
    self.refreshControl=refreshControl;

    UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
    [infoButton addTarget:self action:@selector(aboutUs:) forControlEvents:UIControlEventTouchUpInside];
    //add info button in the navigation controller
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton] ;

    //initialize location manager
    locationManager=[[CLLocationManager alloc] init];

    //to get location
    geocoder=[[CLGeocoder alloc] init];


    //show network activity
    [UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE;

    locationManager.delegate=self;
    locationManager.desiredAccuracy=kCLLocationAccuracyBest;

    //call the location manager update function
    [locationManager startUpdatingLocation];

}



-(void)refresh:(id)sender {

       //update table data
    [locationManager startUpdatingLocation];
    [self.refreshControl endRefreshing];
    [self.tableView reloadData];
}




- (void)dealloc {

    // we are no longer interested in these notifications:
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:kAddEarthquakesNotificationName
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:kEarthquakesErrorNotificationName
                                                  object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:NSCurrentLocaleDidChangeNotification
                                                  object:nil];
}

/**
 Handle errors in the download by showing an alert to the user. This is a very simple way of handling the error, partly because this application does not have any offline functionality for the user. Most real applications should handle the error in a less obtrusive way and provide offline functionality to the user.
 */
- (void)handleError:(NSError *)error {

    NSString *errorMessage = [error localizedDescription];
    NSString *alertTitle = NSLocalizedString(@"Error", @"Title for alert displayed when download or parse error occurs.");
    NSString *okTitle = NSLocalizedString(@"OK ", @"OK Title for alert displayed when download or parse error occurs.");

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:alertTitle message:errorMessage delegate:nil cancelButtonTitle:okTitle otherButtonTitles:nil];
    [alertView show];
}

/**
 Our NSNotification callback from the running NSOperation to add the earthquakes
 */
- (void)addEarthquakes:(NSNotification *)notif {

    assert([NSThread isMainThread]);
    [self addEarthquakesToList:[[notif userInfo] valueForKey:kEarthquakeResultsKey]];

}


/**
 Our NSNotification callback from the running NSOperation when a parsing error has occurred
 */
- (void)earthquakesError:(NSNotification *)notif {

    assert([NSThread isMainThread]);
    [self handleError:[[notif userInfo] valueForKey:kEarthquakesMessageErrorKey]];
}

/**
 The NSOperation "ParseOperation" calls addEarthquakes: via NSNotification, on the main thread which in turn calls this method, with batches of parsed objects. The batch size is set via the kSizeOfFuelPumpBatch constant.
 */
- (void)addEarthquakesToList:(NSArray *)earthquakes {


    NSInteger startingRow = [self.earthquakeList count];
    NSInteger earthquakeCount = [earthquakes count];

    NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:earthquakeCount];



    for (NSInteger row = startingRow; row < (startingRow+earthquakeCount); row++) {

        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        [indexPaths addObject:indexPath];
    }
    NSLog(@"record count %d",earthquakeCount);

   [self.earthquakeList addObjectsFromArray:earthquakes];

  [self.tableView  insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
    //[self.tableView reloadData];

}




#pragma mark - UITableViewDelegate

// The number of rows is equal to the number of earthquakes in the array.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


        return [self.earthquakeList count];
}


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

    static NSString *kEarthquakeCellID = @"EarthquakeCellID";
    citsTableViewCell *cell = (citsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kEarthquakeCellID];

    if(cell==nil)
    {
        cell=[[citsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kEarthquakeCellID];

    }


    // Get the specific earthquake for this row.
    citsFuelFinder *earthquake = (self.earthquakeList)[indexPath.row];

        [cell configureWithEarthquake:earthquake];


    return cell;
}

/**
 * When the user taps a row in the table, display the USGS web page that displays details of the earthquake they selected.
 */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSString *buttonTitle = NSLocalizedString(@"Cancel", @"Cancel");
    //NSString *buttonTitle1 = NSLocalizedString(@"Show USGS Site in Safari", @"Show USGS Site in Safari");
    NSString *buttonTitle2 = NSLocalizedString(@"Show Location in Maps", @"Show Location in Maps");

    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil
                                                       delegate:self
                                              cancelButtonTitle:buttonTitle destructiveButtonTitle:nil
                                              otherButtonTitles: buttonTitle2, nil];
    [sheet showInView:self.view];
}


-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, 500)];
    headerLabel=[[UILabel alloc] initWithFrame:CGRectMake(10, 1.0, 300, 25)];
    headerLabel.numberOfLines=0;
    fuelType=[[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"ULP", @"PULP",@"Diesel",@"LPG", nil]];
    fuelType.frame = CGRectMake(10, 30, 300,25);
    //set first segment selected
    [fuelType setSelectedSegmentIndex:0];
    [fuelType addTarget:self action:@selector(segmentedControlHasChangedValue) forControlEvents:UIControlEventValueChanged];


    headerLabel.font=[UIFont systemFontOfSize:10.0];

    [headerView insertSubview:fuelType aboveSubview:headerLabel];

    [headerView addSubview:headerLabel];

    [headerView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"footer.gif"]]];
    return headerView;

}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

    return 60;
}


#pragma mark -

/**
 * Called when the user selects an option in the sheet. The sheet will automatically be dismissed.
 */
- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex {

    NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    citsFuelFinder *earthquake = (citsFuelFinder *)(self.earthquakeList)[selectedIndexPath.row];

    switch (buttonIndex) {

        case 0: {
            // open the earthquake info in Maps

            // create a map region pointing to the earthquake location
            CLLocationCoordinate2D location = (CLLocationCoordinate2D) { earthquake.latitude, earthquake.longitude };
            NSValue *locationValue = [NSValue valueWithMKCoordinate:location];

            MKCoordinateSpan span = (MKCoordinateSpan) { 2.0, 2.0 };
            NSValue *spanValue = [NSValue valueWithMKCoordinateSpan:span];

            NSDictionary *launchOptions = @{ MKLaunchOptionsMapTypeKey : @(MKMapTypeStandard),
                                            MKLaunchOptionsMapCenterKey : locationValue,
                                            MKLaunchOptionsMapSpanKey : spanValue,
                                            MKLaunchOptionsShowsTrafficKey : @(NO),
                                             MKLaunchOptionsDirectionsModeDriving : @(NO) };

            // make sure the map item has a pin placed on it with the title as the earthquake location
            MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:location addressDictionary:nil];
            MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
            [mapItem setName:earthquake.location];
            [mapItem openInMapsWithLaunchOptions:launchOptions];

            break;
        }
    }

    [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:YES];
}



- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{

    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];

    // Regiser for HUD callbacks so we can remove it from the window at the right time
    HUD.delegate = self;
    HUD.labelText = @"Loading";
    HUD.detailsLabelText = @"updating data";
    HUD.square = YES;

    self.earthquakeList = [NSMutableArray array];
    self.currentEarthquakeObject=nil;

if([self.earthquakeList count] >0)
{
    [self.earthquakeList removeAllObjects];
    [self.tableView reloadData];
}

    // Show the HUD while the provided method executes in a new thread
    [HUD showWhileExecuting:@selector(addEarthquakesToList:) onTarget:self withObject:nil animated:YES];


    NSLog(@"didUpdateToLocation: %@", newLocation);

    CLLocation *currentLocation = newLocation;


     if (currentLocation != nil) {
         NSString *latitude=[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
         NSString *longitude=[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];

         citsTableViewCell *tcell = [[citsTableViewCell alloc] init];
         //set the latitude and longitude
         tcell.lon =[longitude doubleValue];
         tcell.lat = [latitude doubleValue];


         NSLog(@"Lat:%@, Lon:%@", latitude,latitude);
     }




    //stop updating location
    [locationManager stopUpdatingLocation];


    //reverse geocoding
    NSLog(@"Resolving the address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];

            currentLoc=[NSString stringWithFormat:@"%@",placemark.locality];
            if(currentLoc == NULL)
            {
               currentLoc=@"N/A";
            }


            NSLog(@"%@",currentLoc);


            //add text to headertext
            NSDate *currDate=[NSDate date];
            NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"dd/MM/yy HH:mm:ss"];

            NSString *dateString=[dateFormatter stringFromDate:currDate];
            NSString *loc=[NSString stringWithFormat:@"Your location: %@, Updated on: %@", currentLoc, dateString ];


            [dateFormatter setDateFormat:@"EEEE, dd/MM/yyyy"];

            NSString *headerDate=[dateFormatter stringFromDate:currDate];
            headerLabel.text=[NSString stringWithFormat:@"Prices for: %@\n%@", headerDate,loc];


    //currentLoc=[NSString stringWithFormat:@"%@", placemark.locality];
    currentLoc=@"Mirrabooka";

            if(productName==0)
            {
                productName=1;
            }
    NSString *prdStr=[[NSString alloc] initWithFormat:@"%d", productName];

    NSString *str =[currentLoc stringByReplacingOccurrencesOfString:@" " withString:@"%20"];

    NSString *feedURLString =[[NSString alloc] initWithFormat: @"http://www.fuelwatch.wa.gov.au/fuelwatch/fuelWatchRSS?Product=%@&Suburb=%@", prdStr,str ];
    NSURLRequest *earthquakeURLRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:feedURLString]];

            NSLog(@"%@",feedURLString);
    // send the async request (note that the completion block will be called on the main thread)
    //
    // note: using the block-based "sendAsynchronousRequest" is preferred, and useful for
    // small data transfers that are likely to succeed. If you doing large data transfers,
    // consider using the NSURLConnectionDelegate-based APIs.
    //
    [NSURLConnection sendAsynchronousRequest:earthquakeURLRequest queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                               // back on the main thread, check for errors, if no errors start the parsing
                               //
                               [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;


                               // here we check for any returned NSError from the server, "and" we also check for any http response errors
                               if (error != nil) {
                                   [self handleError:error];
                               }
                               else {


                                   // check for any response errors
                                   NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                                   if ((([httpResponse statusCode]/100) == 2) ) {


                                       // Update the UI and start parsing the data,
                                       // Spawn an NSOperation to parse the earthquake data so that the UI is not
                                       // blocked while the application parses the XML data.
                                       //
                                       citsParseOperation *parseOperation = [[citsParseOperation alloc] initWithData:data];
                                       [self.parseQueue addOperation:parseOperation];


                                   }
                                   else {
                                       NSString *errorString =
                                       NSLocalizedString(@"HTTP Error", @"Error message displayed when receving a connection error.");
                                       NSDictionary *userInfo = @{NSLocalizedDescriptionKey : errorString};
                                       NSError *reportError = [NSError errorWithDomain:@"HTTP"
                                                                                  code:[httpResponse statusCode]
                                                                              userInfo:userInfo];
                                       [self handleError:reportError];
                                   }
                               }
                           }];


            // Start the status bar network activity indicator.
    // We'll turn it off when the connection finishes or experiences an error.
    //
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    self.parseQueue = [NSOperationQueue new];



    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(addEarthquakes:)
                                                 name:kAddEarthquakesNotificationName object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(earthquakesError:)
                                                 name:kEarthquakesErrorNotificationName object:nil];


        } else {
            NSLog(@"%@", error.debugDescription);
        }

    } ];

    NSLog(@"%d",[self.earthquakeList count]);


}


-(void)clearData{


    [self.tableView beginUpdates];

        NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
        for (int i = [self.tableView numberOfRowsInSection:0] - 1; i >= 0; i--)
        {
            [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i inSection:0]];
            NSLog(@"Deleted: %d",i);
        }

        [self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationFade];
        [self.earthquakeList removeAllObjects];
        [self.tableView endUpdates];
        //[self.tableView reloadData] ;

}




-(void)segmentedControlHasChangedValue{


    int product;
    product=fuelType.selectedSegmentIndex;
    switch (product) {
        case 0:

            productName=1;

            [locationManager startUpdatingLocation];
            [self clearData];
             break;
        case 1:

            productName=2;
            [self clearData];
            [locationManager startUpdatingLocation];

            break;
        case 2:

            productName=4;
            [self clearData];
           [locationManager startUpdatingLocation];
            break;
        case 3:
            prod![enter image description here][1]uctName=5;

          [self clearData];
        [locationManager startUpdatingLocation];
            break;

    }

    NSLog(@"%d",productName);

    return;

}

@end
#导入“citsViewController.h”
#导入“citsParseOperation.h”
#导入“citsFuelFinder.h”
#导入“citsTableViewCell.h”
#导入“citsAboutViewController.h”
#导入“MBProgressHUD.h”
#进口
//此框架已导入,因此我们可以使用KCFurrerRorNotConnectedPointerNet错误代码
#进口
#进口
@接口citsViewController()
{
CLLocationManager*locationManager;
CLGeocoder*地理编码器;
CLPlacemark*placemark;
NSString*currentLoc;
int产品名称;
}
@属性(非原子)NSMutableArray*地震列表;
@属性(非原子)citsFuelFinder*CurrentEarth地震对象;
@属性(非原子,弱)IBUILabel*位置标签;
//用于管理解析地震数据的NSO操作的队列
@属性(非原子)NSOperationQueue*parseQueue;
@结束
#布拉格标记-
@citsViewController的实现
@综合nomatchesView;
@综合标签;
@合成头标;
@综合燃料类型;
@合成清晰可见;
-(无效)viewDidLoad{
[超级视图下载];
//刷新表格视图
UIRefreshControl*refreshControl=[[UIRefreshControl alloc]init];
[refreshControl添加目标:自我操作:@selector(refresh:)forControlEvents:UIControlEventValueChanged];
self.refreshControl=refreshControl;
UIButton*infoButton=[UIButton按钮类型:UIButtonTypeInfoLight];
[infoButton addTarget:self action:@selector(aboutUs:)for ControlEvents:UIControlEventTouchUpInside];
//在导航控制器中添加信息按钮
self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithCustomView:infoButton];
//初始化位置管理器
locationManager=[[CLLocationManager alloc]init];
//获取位置
地理编码器=[[CLGeocoder alloc]init];
//展示网络活动
[UIApplication sharedApplication].networkActivityIndicatorVisible=TRUE;
locationManager.delegate=self;
locationManager.desiredAccuracy=KCallocationAccuracyBest;
//调用位置管理器更新功能
[locationManager startUpdatingLocation];
}
-(无效)刷新:(id)发件人{
//更新表数据
[locationManager startUpdatingLocation];
[自我刷新控制结束刷新];
[self.tableView重载数据];
}
-(无效)解除锁定{
//我们不再对这些通知感兴趣:
[[NSNotificationCenter defaultCenter]移除观察者:self
名称:KadderthQuakeNotificationName
对象:无];
[[NSNotificationCenter defaultCenter]移除观察者:self
名称:KerthQuakeErrorNotificationName
对象:无];
[[NSNotificationCenter defaultCenter]移除观察者:self
名称:NSCurrentLocaleDidChangeNotification
对象:无];
}
/**
通过向用户显示警报来处理下载中的错误。这是处理错误的一种非常简单的方法,部分原因是该应用程序没有任何供用户使用的脱机功能。大多数真实的应用程序应该以一种不太显眼的方式处理错误,并向用户提供离线功能。
*/
-(无效)句柄错误:(n错误*)错误{
NSString*errorMessage=[error localizedDescription];
NSString*alertTitle=NSLocalizedString(@“错误”,“下载或分析错误时显示的警报标题”);
NSString*OKTTILE=NSLocalizedString(@“OK”,出现下载或分析错误时显示的警报的@“OK Title”);
UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:alertTitle消息:errorMessage委托:nil CancelButtontTitle:okTitle其他ButtontTitles:nil];
[警报视图显示];
}
/**
我们的NSNotification回调来自正在运行的NSO操作,以添加地震
*/
-(无效)添加地震:(NSNotification*)notif{
断言([NSThread isMainThread]);
[自编的ArthQuakesToList:[[notif userInfo]valueForKey:kEarthquakeResultsKey];
}
/**
发生解析错误时,从正在运行的NSO操作发出的NSNotification回调
*/
-(无效)地震错误:(NSNotification*)notif{
断言([NSThread isMainThread]);
[self-handleError:[[notif userInfo]valueForKey:KerthQuakeMessageErrorKey]];
}
/**
NSOperation“ParseOperation”通过主线程上的NSNotification调用AddArthQuakes,而主线程反过来调用此方法,并批量解析对象。批大小通过kSizeOfFuelPumpBatch常量设置。
*/
-(空白)地震列表:(NSArray*)地震{
NSInteger startingRow=[self.earthquakeList count];
NSInteger地震计数=[地震计数];
NSMutableArray*indexPaths=[[NSMutableArray alloc]initWithCapacity:earthquakeCount];
对于(NSInteger row=起始行;row<(起始行+地震计数);row++){
NSIndexPath*indexPath=[NSIndexPath indexPathForRow:row分类:0];
[indexPaths addObject:indexPath];
}
NSLog(@“记录计数%d”,地震计数);
[self.earthquakeList addObjectsFromArray:地震];
[self.tableView insertRowsAtIndexPaths:indexPaths with rownanimation:uitableview rownanimationautomatic];
//[self.tableView重载数据];
}
#pragma标记-UITableViewDelegate
//行数等于数组中的地震数。
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节{
返回[自身地震师计数];
}
-(UITableView单元格*)表格视图:(UITableView*)表格视图
[self.tableView  insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView reloadData];