1

私はかなり新しいiPhone開発者で、問題があります。コードを数時間検索して掘り下げた後、問題の原因は理解できましたが (希望)、解決方法はわかりませんでした。問題は、パーサーが終了する前に tableView セルが読み込まれるため、「[配列カウント]」がゼロになることです。「セクションの行数」を手動で設定すると、テーブルが表示されますが、数秒後に上下にスクロールします。

XMLParser 用と tableView 表示用の 2 つのクラスがあります。この質問を開く前に読んだことによると、tavleviewデータをリロードする必要があるということですが、2つのさまざまなクラスがあるため、その方法がわかりません。何か案は?

ありがとうございます!

ここに私の XMLParser コードがあります:

- (void)parserDidStartDocument:(NSXMLParser *)parser
{ 
    self.titles = [[NSMutableArray alloc]init];
    self.descriptions = [[NSMutableArray alloc]init];
    self.links = [[NSMutableArray alloc]init];
    self.pubDate = [[NSMutableArray alloc]init]; 
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{

}

BOOL isItem = NO;
BOOL isTitle = NO;
BOOL isDesription = NO;
BOOL isImg = NO;
BOOL isPubDate = NO;

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"item"]) {
        isItem = YES;
    }

    if ([elementName isEqualToString:@"title"]) {
        isTitle=YES;
        self.titlesString = [[NSMutableString alloc]init];
    }

    if ([elementName isEqualToString:@"description"]) {
        isDesription = YES;
        self.descriptionString = [[NSMutableString alloc]init];;
        self.data = [NSMutableData data];
    }
    if ([elementName isEqualToString:@"pubDate"]) {
        isPubDate = YES;
        self.pubDateString = [[NSMutableString alloc]init];
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    if(isItem && isTitle){
        [self.titlesString appendString:string];
    }
    if (isItem && isDesription) {
        [self.descriptionString appendString:string];
    }
    if (isItem && isPubDate) {
        [self.pubDateString appendString:string];
    }


}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
    if (self.data)
        [self.data appendData:CDATABlock];

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{



    if ([elementName isEqualToString:@"item"]) {
        isItem = NO;



        [self.titles addObject:self.titlesString];
        [self.descriptions addObject:self.descriptionString];
        [self.pubDate addObject:self.pubDateString];
        NSLog(@"%@,%@,%@,",self.titlesString,self.descriptionString,self.pubDate);

    }

    if ([elementName isEqualToString:@"title"]) {
        isTitle=NO;

    }
    if ([elementName isEqualToString:@"description"]) {
        isDesription = NO;


        if ([self.data length] > 0)
        {
            NSString *htmlSnippet = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
            NSString *imageSrc = [self firstImgUrlString:htmlSnippet];
            [self.links addObject:imageSrc];
        }

        self.data = nil;
    }

    if([elementName isEqualToString:@"pubDate"])
        isPubDate = NO;
}

- (NSString *)firstImgUrlString:(NSString *)string
{
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];

    NSTextCheckingResult *result = [regex firstMatchInString:string
                                                     options:0
                                                       range:NSMakeRange(0, [string length])];

    if (result)
        return [string substringWithRange:[result rangeAtIndex:2]];

    return nil;

}

ここに私のショーtableViewコードがあります:

- (void)viewDidLoad
{
    [super viewDidLoad];

       self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:@selector(toggleLeftView)];

    NSURL *url;

    if (!self.isGetLink)
        url = [NSURL URLWithString:@"http://www.ynet.co.il/Integration/StoryRss2.xml"];
    else
        url = [NSURL URLWithString:self.linkForParsingString];


    if (!self.xmlParser) {
        self.xmlParser = [[XMLparser alloc]init];

        [self.xmlParser LoadXMLWithURl:url];
    }

    self.isGetLink = NO;
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
{

}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.xmlParser.titles count];
}

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


    static NSString *CellIdentifier = @"CustomCell";
    CustomCell *cell = (CustomCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }

    cell.lblTitle.text = [self.xmlParser.titles objectAtIndex:indexPath.row];
    cell.lblTitle.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.xmlParser.links objectAtIndex:indexPath.row]]];
    cell.imgView.image = [UIImage imageWithData:data];


    return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 82;
}


#pragma mark - Table view delegate
NSString *curnentDes;
NSString *currentTitle;
NSString *currentPubDate;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    ReadViewController *rvc = [[ReadViewController alloc]initWithNibName:@"ReadViewController" bundle:nil];
    curnentDes = [self.xmlParser.descriptions objectAtIndex:indexPath.row];
    currentTitle = [self.xmlParser.titles objectAtIndex:indexPath.row];

    currentPubDate = [self.xmlParser.pubDate objectAtIndex:indexPath.row];
    NSDateFormatter *inputFormatter = [[NSDateFormatter alloc]init];

    [inputFormatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"];
    NSDate *inputDate = [inputFormatter dateFromString:currentPubDate];
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc]init];
    [outputFormatter setDateFormat:@"dd/MM/yyyy HH:mm"];
    NSString *outputDate = [outputFormatter stringFromDate:inputDate];

    rvc.description = curnentDes;
    rvc.stitle = currentTitle;
    rvc.pubDate = outputDate;


    [self.navigationController pushViewController:rvc animated:YES];

}
4

2 に答える 2

1

解析が完了したら、テーブルをリロードするだけです。スクロール後にデータが来る理由は、後で配列が更新され、 cellForRowAtIndex が呼び出され、配列にコンテンツがあるため、行が表示されるためです。

注: cellForRow はすべての行に対して呼び出されます (ご存じでしょうか)。

通知の使用:

あなたのパーサークラスで

- (void)parserDidEndDocument:(NSXMLParser *)parser
{ 
  [[NSNotificationCenter defaultCenter ]postNotificationName:@"parsingComplete" object:nil];
}

テーブル ビュー クラスの ViewDidLoad で、このコードを追加し、ur クラスの任意の場所に他の関数を追加します。

あなたのviewDidLoad(編集済み)

- (void)viewDidLoad
{
[super viewDidLoad];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(parsingComplete) name:@"parsingComplete" object:nil];
 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"menuButton.png"] style:UIBarButtonItemStyleBordered target:self.viewDeckController action:@selector(toggleLeftView)];

NSURL *url;

if (!self.isGetLink)
    url = [NSURL URLWithString:@"http://www.ynet.co.il/Integration/StoryRss2.xml"];
else
    url = [NSURL URLWithString:self.linkForParsingString];


if (!self.xmlParser) {
    self.xmlParser = [[XMLparser alloc]init];

    [self.xmlParser LoadXMLWithURl:url];
}

self.isGetLink = NO;
}

//通知を処理する関数:

-(void)parsingComplete
 {
  NSLog(@"parsing results: %@",self.xmlParser.titles); 

  //change your tableViewName

  [yourTableView reloadData];
 }

//通知の削除:

 -(void)dealloc
 {
 [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
于 2013-04-05T06:14:42.007 に答える
0

解析が完了したら、テーブルをリロードします。デリゲート メソッドを使用して、didEndElement メソッドからテーブル ビューを再読み込みします。このように考えてみてください。

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if([elementName isEqualToString:@"Final Element"])
    {

     // Reload your table View using delegates 

    }
}
于 2013-04-05T06:50:19.730 に答える