【问题标题】:UITableView in UIVIew freezes on reload while scrollingUIVIew 中的 UITableView 在滚动时重新加载时冻结
【发布时间】:2016-05-13 17:05:34
【问题描述】:

我有一个 UIViewController,里面有一个 UITableView。我想要一个显示文本的搜索栏,并有一个可以拉出带有选项的 UIPickerView 的 Button。当我从 UIPickerView 中选择任何选项时,tableView 会重新加载。到目前为止,我注意到了两个问题:

  1. 我的 tableView 的每个单元格覆盖大约。高度 400 像素;当我滚动 tableView 并将其留在单元格一半/略多于一半的位置时,我用 0 行重新加载表,整个应用程序冻结,XCode 不记录任何错误

    李>
  2. 当我拉起 Picker 并在后台滚动 tableview 的同时进行选择时,应用程序再次冻结,没有记录任何错误

在任何一种情况下,应用都不会崩溃(不会退出),而是会冻结 UI,从而无法进行任何其他交互。任何形式的帮助将不胜感激。谢谢

以下是代码: - 自定义搜索栏代码 `

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    _leftMonthButton=[[UIButton alloc] initWithFrame:CGRectMake(leftArrowX, 0, leftArrowWidth, 40)];
    _leftMonthButton.imageView.contentMode=UIViewContentModeScaleAspectFit;
    [_leftMonthButton setImage:[UIImage imageNamed:@"arrow-left.png"] forState:UIControlStateNormal];
    [_leftMonthButton addTarget:self action:@selector(monthSwitched:) forControlEvents:UIControlEventTouchUpInside];


    _rightMonthButton=[[UIButton alloc] initWithFrame:CGRectMake(rightArrowX, 0, rightArrowWidth, 40)];
    _rightMonthButton.imageView.contentMode=UIViewContentModeScaleAspectFit;
    [_rightMonthButton setImage:[UIImage imageNamed:@"arrow-right.png"] forState:UIControlStateNormal];
    [_rightMonthButton addTarget:self action:@selector(monthSwitched:) forControlEvents:UIControlEventTouchUpInside];

    _dropDownButton=[UIButton buttonWithType:UIButtonTypeCustom];
    _dropDownButton.frame=CGRectMake(downArrowX, 0, downArrowWidth, 40);
    _dropDownButton.imageView.contentMode=UIViewContentModeScaleAspectFit;
    [_dropDownButton setImage:[UIImage imageNamed:@"downArrow.png"] forState:UIControlStateNormal];
    [_dropDownButton addTarget:self action:@selector(dropDownButtonClicked:) forControlEvents:UIControlEventTouchUpInside];

    _activeMonthIndex=1;

    [self addSubview:_leftMonthButton];
    [self addSubview:_rightMonthButton];
    [self addSubview:_dropDownButton];

    CGRect frame=_dropDownButton.frame;
    frame=CGRectMake(downArrowX, 0, downArrowWidth, 40);
    _dropDownButton.frame=frame;
}


(void)dropDownButtonClicked:(UIButton*)sender
{

    [self.searchBarDelegate brandPickerClicked];
}

(void)monthSwitched:(UIButton*)sender
{
    if (sender==_leftMonthButton)
    {
        if (_activeMonthIndex>0)
        {
            if (_rightMonthButton.alpha==0) _rightMonthButton.alpha=1;
            _activeMonthIndex-=1;
            _monthLabel.text=_activeMonths[_activeMonthIndex];
        }
        if (_activeMonthIndex==0)
        {
            _leftMonthButton.alpha=0;
        }
    }
    else
    {
        if (_activeMonthIndex<2)
        {
            if (_leftMonthButton.alpha==0) _leftMonthButton.alpha=1;
            _activeMonthIndex+=1;
            _monthLabel.text=_activeMonths[_activeMonthIndex];
        }
        if (_activeMonthIndex==2)
        {
            _rightMonthButton.alpha=0;
        }
    }
    [self.searchBarDelegate monthChangedTo:_monthLabel.text];
}`

-tableView实现searchBar的代码

` - (void)viewDidLoad { [超级视图DidLoad]; // 加载视图后做任何额外的设置。

    _searchBar=[[CalendarSearchBar alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 40)];
    _searchBar.searchBarDelegate=self;
    [_headerView addSubview:_searchBar];

    self.calendarTable.dataSource=self;
    self.calendarTable.delegate=self;
    self.calendarTable.allowsSelection=false;

    UIView *tableViewFooter=[[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 23)];
    tableViewFooter.backgroundColor=[UIColor colorwithHexString:@"333333" alpha:1];

    [self.calendarTable setTableFooterView:tableViewFooter];

    _calendar=[CalendarData sharedReleaseData];
    _currentTableRowItems=_calendar;

    CGFloat screenHeight=[UIScreen mainScreen].bounds.size.height;
    CGFloat screenWidth=[UIScreen mainScreen].bounds.size.width;

    _picker=[[UIPickerView alloc] initWithFrame:CGRectMake(0, screenHeight-400, screenWidth, 400.0)];
    _picker.backgroundColor=[UIColor colorwithHexString:@"666666" alpha:1];
    _picker.dataSource=self;
    _picker.delegate=self;
}

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _currentTableRowItems.count;
    }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    calendarCell *cell = (CalendarCell*)[tableView dequeueReusableCellWithIdentifier:@"calendarCell" forIndexPath:indexPath];

    CalendarObject *object=_currentTableRowItems[indexPath.row];

    cell.backgroundColor=[UIColor colorwithHexString:@"333333" alpha:1];
    cell.calendarCardView.backgroundColor=[UIColor whiteColor];
    return cell;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [UIScreen mainScreen].bounds.size.height*479/568;
}

// Picker Controller Delegate Methods
-(void)pickerClicked
{
    if (![_picker isDescendantOfView:self.view])
    {
        [self.calendarTable setContentOffset:CGPointZero animated:YES];
        [self.calendarTable setScrollEnabled:NO];
        [self.view addSubview:_picker];
    }
}

-(void)updateTableViewObjectsWithSearchString:(NSString*)searchString andSearchContext:(SearchContext)searchContext
{
    [_currentTableRowItems removeAllObjects];

    if (searchContext==date)
    {
            for (CalendarObject *object in _calendar.calendarArray)
            {
                if ([object.date.text compare:searchString options:NSCaseInsensitiveSearch]==NSOrderedSame && [object.monthName compare:_searchBar.monthLabel.text options:NSCaseInsensitiveSearch]==NSOrderedSame) [_currentTableRowItems addObject:object];
            }
        }
    }

    dispatch_async(dispatch_get_main_queue(), ^(void){
        [self.releaseCalendarTable reloadData];
    });

   // [self.calendarTable setContentOffset:CGPointZero animated:YES];
}

//Data Source Picker View
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 1;
}

-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    return _searchBar.dates.count;
}

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    NSString *title = _searchBar.dateArray[row];
    NSAttributedString *attString = [[NSAttributedString alloc] initWithString:title attributes:@{
                                                                                                  NSForegroundColorAttributeName: [UIColor whiteColor],
                                                                                                  NSFontAttributeName: [UIFont fontWithName:@"UnitedSansRegTT-Bold" size:18.0f],
                                                                                                  }];
    return attString;
}

//PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
      inComponent:(NSInteger)component
{
    [self.calendarTable setScrollEnabled:YES];
    _searchBar.label.text=_searchBar.brandNames[row];
    [self updateTableViewObjectsWithSearchString:_searchBar.label.text andSearchContext:date];
    [self.picker removeFromSuperview];
}

`

【问题讨论】:

  • 发布您的整个代码,以便我们查看问题所在
  • 我已经添加了代码,如果您需要任何解释,请告诉我

标签: ios uitableview scroll


【解决方案1】:

我想我得到了你的问题,你在 drawrect 上添加子视图。不要这样做,draw rect 只是为了绘制特定的视图。这是一个非常糟糕的做法,将它移动到 initwithframe 中,或者如果附加了一个笔尖,请在awakefromnib 并且不要添加和删除pickerview,在其中创建一个视图将是pickerview并隐藏/显示它

【讨论】:

  • 你想让我为pickerView创建一个单独的视图,让它留在内存中?
  • 你必须明白,创建和销毁 ui 隐藏和显示它们的成本很高,并且视图在可见时会占用更多内存,而其他视图不会占用太多内存。
猜你喜欢
  • 1970-01-01
  • 2018-12-24
  • 2011-10-22
  • 2014-08-06
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多