Я работаю над некоторыми собственными примерами Xamarin, чтобы лучше понять, как создавать приложения для iOS и кодировать C # (у меня больше опыта программирования для Android).
У меня есть представление, в котором я показываю представление коллекции и две кнопки, нажав любую из них, я отправляю HTTP-запрос к Imgur и получаю другой набор изображений. Эти изображения я хочу отображать в представлении коллекции.
Я делаю запросы с помощью следующего метода в своем контроллере:
public void makeRequest(string url){
var request = (HttpWebRequest)WebRequest.Create(url);
request.Headers.Add ("Authorization", "Client-ID " + clientId);
request.Method = "GET";
Task<WebResponse> task = Task.Factory.FromAsync (
request.BeginGetResponse,
asyncResult => request.EndGetResponse (asyncResult),
(object)null);
task.ContinueWith (t => ReadStreamFromResponse (t.Result));
}
Для анализа ответа JSON я использую этот метод (меня интересуют только изображения, а не альбомы):
private void ReadStreamFromResponse(WebResponse response){
using (Stream responseStream = response.GetResponseStream ()) {
using (StreamReader sr = new StreamReader (responseStream)) {
string content = sr.ReadToEnd ();
var json = JsonObject.Parse (content);
var array = json ["data"];
foreach (JsonObject o in array) {
string url = o ["link"];
bool isAlbum = o ["is_album"];
if (!isAlbum) {
url = url.Insert (url.Length - 4, "s");
AddElement (url);
}
}
}
}
}
}
Я использую следующий метод, чтобы добавить изображение в источник:
public void AddElement(string url){
using (var imgUrl = new NSUrl (url)) {
using (var data = NSData.FromUrl (imgUrl)) {
photoSource.photos.Add (UIImage.LoadFromData (data));
InvokeOnMainThread (delegate {
PhotoCollection.ReloadData ();
});
}
}
}
Это мой исходный класс:
class CollectionSource : UICollectionViewSource
{
public List<UIImage> photos;
public CollectionSource(){
photos = new List<UIImage> ();
}
public CollectionSource(List<UIImage> photos){
this.photos = photos;
}
public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath){
var photoCell = (ImageCell)collectionView.DequeueReusableCell ((NSString) ImageCell.CELLID, indexPath);
var photo = photos [indexPath.Row];
photoCell.ImageView.Image = photo;
return photoCell;
}
public override int GetItemsCount(UICollectionView collectionView, int section){
return photos.Count;
}
public override int NumberOfSections(UICollectionView collectionView){
return 1;
}
public override void ItemHighlighted(UICollectionView collectionView, NSIndexPath indexPath){
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.Yellow;
}
public override void ItemUnhighlighted(UICollectionView collectionView, NSIndexPath indexPath){
var cell = collectionView.CellForItem (indexPath);
cell.ContentView.BackgroundColor = UIColor.White;
}
public override bool ShouldHighlightItem(UICollectionView collectionView, NSIndexPath indexPath){
return true;
}
public override bool ShouldShowMenu(UICollectionView collectionView, NSIndexPath indexPath){
return true;
}
public override bool CanPerformAction(UICollectionView collectionView, MonoTouch.ObjCRuntime.Selector action, NSIndexPath indexPath, NSObject sender){
return true;
}
public override void PerformAction(UICollectionView collectionView, MonoTouch.ObjCRuntime.Selector action, NSIndexPath indexPath, NSObject sender){
Console.WriteLine ("Perform action");
}
}
Я избегал использования контроллера CollectionView, потому что мне не нравится оставлять несколько операций только одному классу, я люблю разбивать свой код на классы.
Это мой класс ячеек:
public class ImageCell : UICollectionViewCell
{
public const string CELLID = "ImageCell";
[Export ("initWithFrame:")]
public ImageCell (System.Drawing.RectangleF frame) : base(frame){
this.Initialize ();
}
public UIImageView ImageView {
get;
set;
}
private void Initialize(){
// this.ImageView = new UIImageView (this.ContentView.Bounds);
this.ImageView = new UIImageView (UIImage.FromBundle("placeholder.png"));
this.ContentView.AddSubview (this.ImageView);
}
}
Наконец, это мой класс контроллера представления:
partial class ViewController3 : UIViewController
{
public CollectionSource photoSource;
public ViewController3 (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
PhotoCollection.RegisterClassForCell (typeof(ImageCell), (NSString)ImageCell.CELLID);
photoSource = new CollectionSource ();
PhotoCollection.Source = photoSource;
makeRequest ();
}
// makeRequest, ReadStreamFromResponse and AddElement are located below this method, I won't place them again
}
Как видите, мой код основан на статье Введение в представления коллекций можно найти в руководствах Xamarin. Мне удалось загрузить удаленные изображения, но они не отображаются должным образом в представлении коллекции.
Изображения загружаются, но по мере загрузки они мигают в представлении коллекции, и результат выглядит следующим образом:
По какой-то причине не вся ячейка отображает изображение правильно, возможно, я неправильно обновляю свой CollectionView?