年底第一篇:Xamarin.iOS MJRefresh集成

写在前面:

临近年底,也刚好有时间整理最新我的Github上的一些 Demo,这一年中也使用过不少第三方 SDK,对于 Bindings Liabrary 的转化也有一定心得体会,其实对于 Binding 的难易程度很大程度上跟 Framework 团队的代码质量相关,这里我会介绍一个使用率很广的一个 MJRefresh,同时也会分享Binding的过程。

已经有上百个 App 用到了 MJRefresh (只列出了其中一部分 App ):

年底第一篇:Xamarin.iOS MJRefresh集成_第1张图片
app.png

Set Binding Library

Sharpie Bind

这里一般我们使用的方法有两种,这两种方法在之前的博客中都有介绍,如果不清楚的话可以查看一下:

  • 手动使用类库转化工具转换
  • 使用CocoaPods自动转换

Bindings Library的错误处理

首先我们需要处理ApiDefinition.cs文件中的错误,这些错误一般都只会有几类,挨个解决就好了:

  1. nint, nuint类型错误
    一般 nint 需要转换为 C# 的类型,我这里把它转换成 ulong/long 就基本上完事了

  2. [Verify(MethodToProperty)]标签
    这个标签是因为在OC是一个静态方法,C#会帮你转换成属性,遇到含有类似这种标签的错误,你可以删除/注释掉它。还有一些提示出错的如BaseType不用理,这个只是编辑器不支持这个标签,不影响项目编译和运行。

年底第一篇:Xamarin.iOS MJRefresh集成_第2张图片
error.png
  1. cannot declare instance members in a static class
    这一类问题都是由于扩展的方法不能被识别一起的,需要把每个属性的get/set通过方法描述解决,这里我们拿一个例子来说,原始转化好的代码如下:
// @property (nonatomic, strong) MJRefreshHeader * mj_header;
[Export ("mj_header", ArgumentSemantic.Strong)]
MJRefreshHeader Mj_header { get; set; }

// @property (nonatomic, strong) MJRefreshFooter * mj_footer;
[Export ("mj_footer", ArgumentSemantic.Strong)]
MJRefreshFooter Mj_footer { get; set; }

修改后的代码如下:

// @property (nonatomic, strong) MJRefreshHeader * mj_header;
[Export("header")]
MJRefreshHeader Header();

[Export("setHeader:")]
void SetHeader(MJRefreshHeader header);

// @property (nonatomic, strong) MJRefreshFooter * mj_footer;
[Export("footer")]
MJRefreshFooter Footer();

[Export("setFooter:")]
void SetFooter(MJRefreshFooter header);
  1. 指针
    在C#中是没有指针概念的,但 Objective-C 有 ,转换的时候有时候不会消除 *,这个时候你只需要把 * 去掉

一般最初的错误提示有这么几种,但是这些并不是绝对的,有些库转化后也会出现 类名大小错误重分类定义缺少系统库引用 等错误,像这些错误一般我们通过手动修改,注释,添加系统库引用即可。


使用 MJRefresh

在我们完成Binding Library的项目之后呢,我们可以开始实现相应的功能了,这里我们将使用 MJRefresh 来自定义 TableView的下拉刷新动画,这里我们通过每次上拉或下拉刷新来改变 Count 的值:

  • 设置默认的 MJRefresh HeaderFooter 样式:
            table = new UITableView();
            table.Frame = new CoreGraphics.CGRect(0, 40, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height - 64 - 40);
            table.DataSource = new TableDataSource(this);
            table.Delegate = new TableDelegate(this);
            this.View.AddSubview(table);

            MJRefreshNormalHeader header = new MJRefreshNormalHeader();
            table.SetHeader(header);

            MJRefreshAutoNormalFooter footer = new MJRefreshAutoNormalFooter();
            table.SetFooter(footer);

            header.RefreshingBlock = async () => {
                await Task.Delay(2000);
                InvokeOnMainThread(() => {
                    footer.Hidden = true;
                    this.Count += 12;
                    table.ReloadData();
                    table.Header().EndRefreshing();
                    footer.Hidden = false;

                });
            };

            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshHeaderIdleText"), MJRefreshState.Idle);
            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshHeaderPullingText"), MJRefreshState.Pulling);
            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshHeaderRefreshingText"), MJRefreshState.Refreshing);

            header.AutomaticallyChangeAlpha = true;


            footer.RefreshingBlock = async () => {
                await Task.Delay(2000);
                InvokeOnMainThread(() => {
                    footer.Hidden = true;
                    this.Count += 5;
                    table.ReloadData();
                    table.Footer().EndRefreshing();
                    footer.Hidden = false;
                });
            };

            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterIdleText"), MJRefreshState.Idle);
            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterRefreshingText"), MJRefreshState.Refreshing);
            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterNoMoreDataText"), MJRefreshState.NoMoreData);



            table.Header().BeginRefreshing();
  • 同时我们需要设置 TableViewDelegateDataSource,这里我们将 Count 的值设置为 TableView 的行数:
    public class TableDelegate : UITableViewDelegate
    {
        private ViewController _vc;
        public TableDelegate(ViewController vc)
        {
            _vc = vc;
        }
        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {
            _vc.NavigationController.PushViewController(new MJTableViewController(), true);
        }
    }

    public class TableDataSource : UITableViewDataSource
    {
        private ViewController _vc;
        public TableDataSource(ViewController vc)
        {
            _vc = vc;
        }
        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {
            UITableViewCell cell = tableView.DequeueReusableCell("testcell");
            if (cell == null)
                cell = new UITableViewCell(UITableViewCellStyle.Default, "testcell");
            if(indexPath.Row % 2 != 0)
                cell.TextLabel.Text = "push";
            else
                cell.TextLabel.Text = "modal";
            return cell;
        }

        public override nint RowsInSection(UITableView tableView, nint section)
        {
            return _vc.Count;
        }
    }
年底第一篇:Xamarin.iOS MJRefresh集成_第3张图片
default.gif
  • 同样我们可以自定义 HeaderFooter 的样式,这里我们设置 Header 为一个自定义的 Gif 动画显示效果,同时添加模式请求头文字:
           MJChiBaoZiHeader header = new MJChiBaoZiHeader();
            this.TableView.SetHeader(header);

            MJRefreshAutoNormalFooter footer = new MJRefreshAutoNormalFooter();
            this.TableView.SetFooter(footer);

            header.RefreshingBlock = async () => {
                await Task.Delay(2000);
                InvokeOnMainThread(() => {
                    footer.Hidden = true;
                    this.Count += 12;
                    this.TableView.ReloadData();
                    this.TableView.Header().EndRefreshing();
                    footer.Hidden = false;

                });
            };

            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle),"MJRefreshHeaderIdleText"), MJRefreshState.Idle);
            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshHeaderPullingText"), MJRefreshState.Pulling);
            header.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshHeaderRefreshingText"), MJRefreshState.Refreshing);

            header.AutomaticallyChangeAlpha = true;


            footer.RefreshingBlock = async () => {
                await Task.Delay(2000);
                InvokeOnMainThread(() => {
                    footer.Hidden = true;
                    this.Count += 5;
                    this.TableView.ReloadData();
                    this.TableView.Footer().EndRefreshing();
                    footer.Hidden = false;
                });
            };

            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterIdleText"), MJRefreshState.Idle);
            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterRefreshingText"), MJRefreshState.Refreshing);
            footer.SetTitle(NSBundle_MJRefresh.Mj_localizedStringForKey(NSBundle_MJRefresh.Mj_refreshBundle(NSBundle.MainBundle), "MJRefreshAutoFooterNoMoreDataText"), MJRefreshState.NoMoreData);



            this.TableView.Header().BeginRefreshing();
  • 这里的 MJChiBaoZiHeader 继承自 MJRefreshGifHeader,我们只需要设置不同状态下显示的静态图片就能达到 Gif 的效果:
using System;
using MJRefresh;
using UIKit;

using Foundation;
using System.Collections.Generic;

namespace Test_MJRefresh.DIY
{
    public class MJChiBaoZiHeader : MJRefreshGifHeader
    {
        public override void Prepare()
        {
            base.Prepare();

            NSMutableArray refreshImages = new NSMutableArray();

            for (int i = 1; i < 3;i++)
            {
                UIImage image = new UIImage($"dropdown_loading_0{i}");
                refreshImages.Add(image);
            }

            this.SetImages(refreshImages, MJRefreshState.Pulling);

            this.SetImages(refreshImages , MJRefreshState.Refreshing);
        }
    }
}
年底第一篇:Xamarin.iOS MJRefresh集成_第4张图片
image.gif

完整 Demo 可以访问 项目地址
或者直接添加 Xamarin.iOS.MJRefresh Nuget 到项目中进行使用。

到这里Xamarin.iOS MJRefresh集成的介绍就完成了,希望能对您有所帮助。


——End 有问题可以加我微信,大家一起讨论,加好友前请备注您的简称,谢谢!

年底第一篇:Xamarin.iOS MJRefresh集成_第5张图片

你可能感兴趣的:(年底第一篇:Xamarin.iOS MJRefresh集成)