2013-10-14 3 views
1

UICollectionView (컨트롤러)를 처음 사용하는 중입니다. TableViews를 사용하는 것만 큼 간단해야합니다.UICollectionView - 흥미로운 흐름 레이아웃

흐름 (여러 행)의 모든 이미지를 표시하는 대신 맨 위 행만 표시됩니다. 다른 모든 이미지는 어딘가에 있습니다 ... 스크롤이 가능하지만 아무런 반응이 없으며, 튀어 나오거나 스크롤하지 않습니다. 오리엔테이션 변경 후 (그리고 뒤로) 더 많은 이미지가 표시되지만 무작위로 나타납니다. 모든 방향 변경 후 다른 위치에 나타납니다.

예제에는 7 개의 이미지가 있어야합니다. IB에서

내 속성 : IB Settings Screenshot

처음 : After rotating

그리고 내 소스 코드를 사진 갤러리를 구현하기 : First time

(뒤로) 회전 후.

using System; 

using MonoTouch.Foundation; 
using MonoTouch.UIKit; 
using System.Collections.Generic; 
using Xamarin.Media; 
using MonoTouch.AssetsLibrary; 
using MonoTouch.CoreGraphics; 
using System.Diagnostics; 
using System.Linq; 
using System.Drawing; 

namespace B2.Device.iOS 
{ 
    public partial class TagesRapportDetailRegieBilderCollectionViewController : UICollectionViewController 
    { 
     private const string Album = "Rapport"; 

     public TagesRapportDetailRegieBilderSource Source { get; private set; } 
     private TagesRapportDetailRegieBilderDelegate _delegate; 

     public TagesRapportDetailRegieBilderCollectionViewController (IntPtr handle) : base (handle) 
     { 
      Source = new TagesRapportDetailRegieBilderSource(this); 
      _delegate = new TagesRapportDetailRegieBilderDelegate(this); 

      // Delegate - Muss im konstruktor sein. ViewDidLoad geht nicht! 
      CollectionView.Delegate = _delegate; 
     } 

     public override void ViewDidLoad() 
     { 
      base.ViewDidLoad(); 

      // Cell Klasse registrieren 
      CollectionView.RegisterClassForCell (typeof(ImageCell), new NSString("imageCell")); 

      // DataSource 
      CollectionView.Source = Source; 

      // Bilder laden 
      LoadImages(); 
     } 

     private void LoadImages() 
     { 
      Source.Images.Clear(); 

      var assetsLibrary = new ALAssetsLibrary(); 
      assetsLibrary.Enumerate(ALAssetsGroupType.Album, GroupsEnumeration, GroupsEnumerationFailure); 
     } 

     private void GroupsEnumeration(ALAssetsGroup group, ref bool stop) 
     { 
      if (group != null && group.Name == Album) 
      { 
       //notifies the library to keep retrieving groups 
       stop = false; 

       //set here what types of assets we want, 
       //photos, videos or both 
       group.SetAssetsFilter(ALAssetsFilter.AllPhotos); 

       //start the asset enumeration 
       //with ALAssetsGroup's Enumerate method 
       group.Enumerate(AssetsEnumeration); 

       CollectionView.ReloadData(); 
      } 
     } 

     private void AssetsEnumeration(ALAsset asset, int index, ref bool stop) 
     { 
      if (asset != null) 
      { 
       //notifies the group to keep retrieving assets 
       stop = false; 

       //use the asset here 
       var image = new UIImage(asset.AspectRatioThumbnail()); 

       Source.Images.Add(image); 
      } 
     } 

     private void GroupsEnumerationFailure(NSError error) 
     { 
      if (error != null) 
      { 
       new UIAlertView("Zugriff verweigert", error.LocalizedDescription, null, "Schliessen", null).Show(); 
      } 
     } 
    } 

    public class TagesRapportDetailRegieBilderDelegate : UICollectionViewDelegateFlowLayout 
    { 
     private TagesRapportDetailRegieBilderCollectionViewController _controller; 

     public TagesRapportDetailRegieBilderDelegate(TagesRapportDetailRegieBilderCollectionViewController controller) 
     { 
      _controller = controller; 
     } 

     public override System.Drawing.SizeF GetSizeForItem(UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath) 
     { 
      var size = _controller.Source.Images[indexPath.Row].Size.Width > 0 
       ? _controller.Source.Images[indexPath.Row].Size : new SizeF(100, 100); 

      size.Width /= 3; 
      size.Height /= 3; 

      return size; 
     } 

     public override UIEdgeInsets GetInsetForSection(UICollectionView collectionView, UICollectionViewLayout layout, int section) 
     { 
      return new UIEdgeInsets(50, 20, 50, 20); 
     } 
    } 

    public class TagesRapportDetailRegieBilderSource : UICollectionViewSource 
    { 
     private TagesRapportDetailRegieBilderCollectionViewController _controller; 

     public List<UIImage> Images { get; set; } 

     public TagesRapportDetailRegieBilderSource(TagesRapportDetailRegieBilderCollectionViewController controller) 
     { 
      _controller = controller; 
      Images = new List<UIImage>(); 
     } 

     public override int NumberOfSections(UICollectionView collectionView) 
     { 
      return 1; 
     } 

     public override int GetItemsCount(UICollectionView collectionView, int section) 
     { 
      return Images.Count; 
     } 

     public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath) 
     { 
      var cell = collectionView.DequeueReusableCell(new NSString("imageCell"), indexPath) as ImageCell; 

      cell.Image = Images[indexPath.Row]; 

      return cell; 
     } 
    } 

    public class ImageCell : UICollectionViewCell 
    { 
     UIImageView imageView; 

     [Export ("initWithFrame:")] 
     public ImageCell (System.Drawing.RectangleF frame) : base (frame) 
     { 
      imageView = new UIImageView(frame); 
      imageView.AutoresizingMask = ~UIViewAutoresizing.None; 
      ContentView.AddSubview (imageView); 
     } 

     public UIImage Image 
     { 
      set 
      { 
       imageView.Image = value; 
      } 
     } 
    } 
} 

답변

1

만약 당신이 GetSizeForItem이 처음부터 필요는 없습니다 오버라이드 (override), 균일 한 격자 세포를 표시 할 할 수 있기를 바랍니다. IB 또는 ViewDidLoad 동안 프로그래밍 방식으로 플로우 레이아웃의 셀 크기 (cellize) 속성을 설정하고 끝내면됩니다.

코드에 또 다른 문제가 있습니다 :

group.Enumerate(AssetsEnumeration) 

이 비동기 적으로 실행됩니다. 의미 :

CollectionView.ReloadData(); 

이미지의 일부만 처리합니다. 열거가 완료되었음을 나타내는 group == null 일 때 ReloadData()를 발행하는 것이 좋습니다.

ReloadData alltogether를 피하고 이미지를 추가 할 때마다 CollectionView.InsertItem()을 호출 할 수도 있습니다. 이렇게하면 항목이 모두 열거 된 후 곧바로 모든 항목이 표시되는 대신 항목이 즉시 표시 될 수 있습니다. 이는 기기에서 다소 시간이 걸릴 수 있습니다. 단점은 당신이 this에 빠지지 않도록 조심해야한다는 것입니다.

+0

저는 이진 화가 64KB보다 커지므로 Rx 구성 요소를 사용할 수 없으므로이 문제가 발생합니다. 저는 Starter 계정에 있습니다. 내용을 스크롤 할 때 내 컬렉션보기가 깜박이며 원격 API에서 가져온 일부 이미지 만 렌더링됩니다. 나에게 남은 옵션은 무엇입니까? –

관련 문제