2017-10-25 11 views
0

연락처를 선택한 후 단일 셀만 다시로드하려는 경우 (method didSelect contact). 셀의 항목 수가 커지면 프로세스가 느려집니다. 나는 또한 DispatchQueue.main.async { code }에 구현하려고 시도하고로드하는 데 약간의 시간이 필요합니다.Swift - UICollectionView reloadItems가 너무 오래 걸립니다.

cellForItemAt 및 noOfItemInSection (AddCell) - 전체 셀 4

var indexPaths = [IndexPath]() 

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
    indexPaths.append(indexPath) 

    if indexPath.item == 1 { 
     let addCell = collectionView.dequeueReusableCell(withReuseIdentifier: CellId, for: indexPath) as! AddCell 
     addCell.btnAdd.addTarget(self, action: #selector(handleOpenContact), for: .touchUpInside) 
     addCell.invitees = invitees 
     return addCell 
    } 
} 

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 4 
    } 

cellForItemAt 및 noOfItemInSection (SubAddCell)

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: subAddId, for: indexPath) as! SubAddCell 
     cell.delegate = self 
     cell.invitee = invitees[indexPath.item] 
     return cell 
    } 

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return invitees.count 
    } 

didSelect (ContactPicker)

func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) { 
     let invitee = Invitee() 
     invitee.name = contact.givenName 

     if contact.isKeyAvailable(CNContactPhoneNumbersKey) { 
      for phoneNumber: CNLabeledValue in contact.phoneNumbers { 
       let a = phoneNumber.value 
       print("\(a.stringValue)") 
       invitee.phoneNo = a.stringValue 
      } 
     } 
     self.invitees.append(invitee) 

     for index in self.indexPaths { 
      if index == [0, 0] { 
       print(index) 
       self.collectionView?.reloadItems(at: [index]) 
      } 
     } 
    } 

방법에서 indexPaths의 값을 얻었습니다. 초대 대상자가 5 개의 항목을 포함하면 print(index)은 19 개의 값을 인쇄합니다. 나는 이유를 모른다. 아래 이미지가 있습니다. reloadItems을 최적화하는 방법 UI

enter image description here

enter image description here

디자인?

정말 도움이됩니다. 많은 감사합니다.

+0

'cellForItemAtIndexPath' 메소드의 나머지 부분을 설명 할 수 있습니까? 당신은 인덱스 1에서 셀을 처리하는 것으로 나타났습니다 ... 반면에 분명히 19 개의 셀이 사용되었습니다. 나머지 방법은 무엇입니까? – murphguy

+0

@murphguy, 그것은 단지 4 셀이었습니다. 그 특정 셀에 대해서는 그 안에'UICollectionView'가 있어야합니다. 질문을 업데이트했습니다. – Nizzam

+0

그 안에는 당신의 도전이 있습니다. 접을 수있는 셀 애니메이션/처리는 다소 무겁습니다. 그래서 그것은에 달려 있습니다 : 당신은 세포 내에서 자동 레이아웃을 사용하고 있습니까? 셀의 내용은 동적입니까? 별도의 스레드를 통해 이미지를 비동기 적으로로드합니까? 이 세 가지 질문은 왜 앱이 뒤떨어져 있는지에 대한 질문에 대답해야합니다. – murphguy

답변

0

indexPaths.append(indexPath)cellForItemAt 인 것으로 생각하여 데이터를 다시로드 한 후에 indexPaths가 증가 할 수있는 이유는 무엇입니까? NSArray 대신 NSSet을 사용하여 객체가 고유한지 확인할 수 있습니다.

그리고 : cell.invitee = invitees[indexPath.item], 당신은 invitee에 대해 didSet을 구현 했습니까? 그랬다면 백그라운드 대기열에서 먼저 데이터를 준비해야한다고 생각합니다. 예 :

DispatchQueue(label: "queue").async { 
    let image = <# process image here #> 
    let name = <# process name here #> 
    DispatchQueue.main.async { 
    self.imageView.image = image 
    self.label.text = name 
    } 
} 

희망 사항은 도움을 줄 수 있습니다!

+0

나는'invitee'에 대해 didSet을 구현했다. NSSet을 IndexPath로 설정해야합니까? 나는 당신을 얻지 못했다. – Nizzam

+0

-'didSet'이 UI 요소를 채우기 위해 데이터를 처리하는 데 많은 시간이 걸리는 것으로 보입니다. - NSSet은 indexPath가 중복되지 않도록합니다! –

0

Collectionviews은 iOS에서 가장 강력한 UI 도구이지만 잘못 수행되거나 잘못 사용되면 (걱정할 필요없이) UX에 악영향을 미칠 수 있습니다. . 이 물건이 어떻게 영향을 받는지 보려면 XCode Tools를 읽고 UI 성능을 디버깅하는 방법을 읽어보십시오.

중요 사항 고려해야 할

프레임 단위 작업 (즉, 당신의 collectionviewcell, 확장 또는 확장되지 않은 넣기) 부드러운 스크롤을 위해 실행하는 데 더 이상 17 ms보다 소요됩니다.

UICollectionView performance - _updateVisibleCellsNow

그래서 당신은 가능한 한 당신의 세포가 간단하고 효율적으로 확인해야합니다. 특히 확장 가능한 셀에 collectionviews과 같은 복잡한 하위보기가 포함 된 경우 가장 좋습니다.