Xamarin.iOS 波浪效果
2016-12-21 11:49
387 查看
以前Android写过一个demo,是波浪效果,应该是仿照百度外卖的那个头像效果。突然想拿Xamarin来试试,利用我的脑洞终于给弄出来了,不知道方法是不是合理。先贴出来展示一下吧.
实际效果是波浪在动,头像以及文字也在上下动,给人一种效果就是头像和文字是漂在波浪上面的。
下面来说一下实现吧:
首先将看见的这个view分成三个view,分别实现。第一个view就是波浪view,即如下图
就是类似一个正弦曲线的这么一个效果。
第二个就是头像加文字的view,把她单独出来做一个view目的就是可以单独控制它的动画来配合波浪的动画。
下面首先来看看波浪view的画法:新建一个View继承UIView。通过Draw方法来画线,想要实现波浪效果让它动起来,最少要画两个屏幕长度的波浪,这个大家应该能理解吧。
还有一点注意的就是我没有找到直接画正弦的方法,最后是用贝塞尔曲线拼接而成的。
看下代码:
上面我将整个类都贴出来,因为没啥难度,不过有一点要注意的,就是在波浪下凹处仔细看会有一点透明白色的区域,这个区域我是将右半边弧度用了一个透明颜色填充了。大家可以自己换。
头像和文字的view我就不占用这里的地方了,没什么要注意的。
下面直接贴出来整体的View的类:
注:
1.代码中最下面部分就是波浪view与头像view的动画。波浪view还好说,就是一个循环左移的动画,头像的动画的轨迹分析一下:一个正弦函数移动,应该是先向下移动一个驼峰距离,在向上移动两个驼峰距离,在向下移动一个驼峰距离。这是一个完整的周期,下一个动画循环这个周期即可。
2.代码中使用了一种控件间的约束方式,大家可以换成自己的,如果需要的话可以私聊我。
3.动画属性我设置的是匀速的,即UIViewAnimationOptions.CurveLinear这里,相关属性大家查ios原生的就可以查到。
4.本人水平有限,可能用的都是特别简单的东西来实现这个功能,可能多走了些弯路或者有更好的实现方式,希望大家可以多多提建议,共同进步。
实际效果是波浪在动,头像以及文字也在上下动,给人一种效果就是头像和文字是漂在波浪上面的。
下面来说一下实现吧:
首先将看见的这个view分成三个view,分别实现。第一个view就是波浪view,即如下图
就是类似一个正弦曲线的这么一个效果。
第二个就是头像加文字的view,把她单独出来做一个view目的就是可以单独控制它的动画来配合波浪的动画。
下面首先来看看波浪view的画法:新建一个View继承UIView。通过Draw方法来画线,想要实现波浪效果让它动起来,最少要画两个屏幕长度的波浪,这个大家应该能理解吧。
还有一点注意的就是我没有找到直接画正弦的方法,最后是用贝塞尔曲线拼接而成的。
看下代码:
using System; using System.Drawing; using CoreGraphics; using UIKit; namespace RuilaiGrow.iOS { /// <summary> /// 波浪View /// by ge /// </summary> public class WaveView : UIView { //正线曲线,顶部,中线,底部Y轴高度 private nfloat _waveTop = 50f; private nfloat _waveHalfHei = 65f; private nfloat _waveBottom = 80f; public WaveView() { this.Frame = new RectangleF(0, 0, (float)(UIScreen.MainScreen.Bounds.Width * 2), (float)_waveBottom); this.BackgroundColor = UIColor.White; } //划线 public override void Draw(CoreGraphics.CGRect rect) { base.Draw(rect); //本View上半部分红色背景矩形 CGContext contextBac = UIGraphics.GetCurrentContext(); contextBac.SetFillColor(MvxTouchColor.DeepRed.CGColor); contextBac.AddRect(new RectangleF(0, 0, (float)(UIScreen.MainScreen.Bounds.Width * 2), (float)_waveHalfHei)); contextBac.FillPath(); //屏幕的宽度 nfloat viewWid = UIScreen.MainScreen.Bounds.Width; //利用贝塞尔曲线完成正弦波浪曲线 //分成两次画出正弦曲线 for (int i = 0; i < 2; i++) { nfloat startX = i * viewWid; //左半边弧 CGContext contextLeft = UIGraphics.GetCurrentContext(); contextLeft.SetLineWidth(1f); contextLeft.SetStrokeColor(MvxTouchColor.DeepRed.CGColor); contextLeft.MoveTo(startX, _waveHalfHei); contextLeft.AddCurveToPoint(startX, _waveHalfHei, (startX + viewWid / 4), _waveTop, (startX + viewWid / 2), _waveHalfHei); contextLeft.SetFillColor(MvxTouchColor.White.CGColor); contextLeft.DrawPath(CGPathDrawingMode.EOFill); //右半边弧 CGContext contextRight = UIGraphics.GetCurrentContext(); contextRight.SetLineWidth(1f); contextRight.SetStrokeColor(MvxTouchColor.DeepRed.CGColor); contextRight.MoveTo((startX + viewWid / 2), _waveHalfHei); contextRight.AddCurveToPoint((startX + viewWid / 2), _waveHalfHei, (startX + (System.nfloat)(viewWid * 0.75)), _waveBottom, startX + viewWid, _waveHalfHei); contextRight.SetFillColor(MvxTouchColor.AlphaDeepRed.CGColor); contextRight.DrawPath(CGPathDrawingMode.EOFill); } } } }
上面我将整个类都贴出来,因为没啥难度,不过有一点要注意的,就是在波浪下凹处仔细看会有一点透明白色的区域,这个区域我是将右半边弧度用了一个透明颜色填充了。大家可以自己换。
头像和文字的view我就不占用这里的地方了,没什么要注意的。
下面直接贴出来整体的View的类:
注:
1.代码中最下面部分就是波浪view与头像view的动画。波浪view还好说,就是一个循环左移的动画,头像的动画的轨迹分析一下:一个正弦函数移动,应该是先向下移动一个驼峰距离,在向上移动两个驼峰距离,在向下移动一个驼峰距离。这是一个完整的周期,下一个动画循环这个周期即可。
2.代码中使用了一种控件间的约束方式,大家可以换成自己的,如果需要的话可以私聊我。
3.动画属性我设置的是匀速的,即UIViewAnimationOptions.CurveLinear这里,相关属性大家查ios原生的就可以查到。
4.本人水平有限,可能用的都是特别简单的东西来实现这个功能,可能多走了些弯路或者有更好的实现方式,希望大家可以多多提建议,共同进步。
using System; using System.Drawing; using CoreGraphics; using RuilaiGrow.iOS.Common; using UIKit; namespace RuilaiGrow.iOS { /// <summary> /// 里程碑模块主页顶部头像View /// by ge /// </summary> public class UserHeaderView : UIView { private nfloat _waveBottom = 80f; private nfloat _waveTopHei = 7f; //波浪条 private WaveView _waveView = null; public WaveView WaveView { get { if (_waveView == null) { _waveView = new WaveView(); } return _waveView; } } //头像,名字,年龄布局 private UIView _headerView = null; public UIView HeaderView { get { if (_headerView == null) { _headerView = new UIView(); _headerView.AddSubview(HeaderImg); _headerView.AddSubview(NameText); _headerView.AddSubview(AgeText); } return _headerView; } } //头像 private UIButton _headerImg = null; public UIButton HeaderImg { get { if (_headerImg == null) { _headerImg = new UIButton(); _headerImg.SetImage(UIImage.FromFile("icon_child_head.png"), UIControlState.Normal); } return _headerImg; } } //名字 private UILabel _nameText = null; public UILabel NameText { get { if (_nameText == null) { _nameText = new UILabel(); _nameText.Text = "小贝"; _nameText.TextAlignment = UITextAlignment.Left; _nameText.TextColor = MvxTouchColor.White; _nameText.Font = UIFont.SystemFontOfSize(18f); return _nameText; } return _nameText; } } //月龄 private UILabel _ageText = null; public UILabel AgeText { get { if (_ageText == null) { _ageText = new UILabel(); _ageText.Text = "43个月"; _ageText.TextAlignment = UITextAlignment.Left; _ageText.TextColor = MvxTouchColor.GraySix; _ageText.Font = UIFont.SystemFontOfSize(13f); } return _ageText; } } /// <summary> /// 构造函数 /// 设定背景色与frame /// </summary> public UserHeaderView() { this.Frame = new RectangleF(0, 0, (float)UIScreen.MainScreen.Bounds.Width, (float)_waveBottom); this.BackgroundColor = UIColor.White; } //提交view public override void LayoutSubviews() { base.LayoutSubviews(); nfloat textMarTop = 6f; nfloat marBottom = 6f; this.AddSubview(WaveView); this.AddSubview(HeaderView); //一种aotolayout方式进行view约束 this.ConstrainLayout(() => HeaderView.Frame.Bottom == this.Frame.Bottom - marBottom && HeaderView.Frame.Width == this.Frame.Width && HeaderView.Frame.Height == this.Frame.Height - marBottom ); HeaderView.ConstrainLayout(() => HeaderImg.Frame.Bottom == HeaderView.Frame.Bottom && HeaderImg.Frame.GetCenterX() == HeaderView.Frame.GetCenterX() && NameText.Frame.Top == HeaderImg.Frame.Top + textMarTop && NameText.Frame.Left == HeaderImg.Frame.Right + textMarTop && NameText.Frame.Right == HeaderView.Frame.Right && AgeText.Frame.Top == NameText.Frame.Bottom && AgeText.Frame.Left == HeaderImg.Frame.Right + textMarTop && AgeText.Frame.Right == HeaderView.Frame.Right ); //开启动画 startAnimation(UIScreen.MainScreen.Bounds.Width); } /// <summary> /// 开始波浪动画 动画结束监听中重启本方法 /// </summary> /// <param name="leftMove">Left move.</param> public void startAnimation(nfloat leftMove) { startHeadAnimation(_waveTopHei, true); var waveFrame = WaveView.Frame; waveFrame.X = WaveView.Frame.X - leftMove; UIView.Animate(12d, 0d, UIViewAnimationOptions.CurveLinear, () => WaveView.Frame = waveFrame, () => { waveFrame.X = WaveView.Frame.X + leftMove; WaveView.Frame = waveFrame; /** 动画完成监听 **/ startAnimation(leftMove); }); } /// <summary> /// 头像初次view动画 /// </summary> /// <param name="waveTopHei">Wave top hei.</param> public void startHeadAnimation(nfloat waveTopHei, bool isFirst) { var headerFrame = HeaderView.Frame; headerFrame.Y = HeaderView.Frame.Y + waveTopHei; UIView.Animate(3d, 0d, UIViewAnimationOptions.CurveLinear, () => HeaderView.Frame = headerFrame, () => { waveTopHei = waveTopHei * 2; waveTopHei = -waveTopHei; if (!isFirst) return; /** 动画完成监听 **/ startHeadAnimationAgain(waveTopHei); }); } /// <summary> /// 头像view动画 /// </summary> /// <param name="waveTopHei">Wave top hei.</param> public void startHeadAnimationAgain(nfloat waveTopHei) { var headerFrame = HeaderView.Frame; headerFrame.Y = HeaderView.Frame.Y + waveTopHei; UIView.Animate(6d, 0d, UIViewAnimationOptions.CurveLinear, () => HeaderView.Frame = headerFrame, () => { waveTopHei = waveTopHei / 2; waveTopHei = -waveTopHei; /** 动画完成监听 **/ startHeadAnimation(waveTopHei, false); }); } } }
相关文章推荐
- Xamarin.iOS故事板(Storyboard)使用_传值与视图切换效果
- iOS开发封装篇-模仿百度外卖波浪头像效果
- 论坛源码推荐(4月28日):列表项目的波浪效果 兼容iOS 6与iOS 7的自定义导航条
- iOS 仿百度外卖-个人中心(头像波浪效果)
- Xamarin ios 自定义UIView 实现Alert弹窗效果
- iOS 扩展性极强的波浪效果工具类
- iOS实现百度外卖头像波浪的效果
- iOS 扩展性极强的波浪效果工具类
- iOS CAShapeLayer、CADisplayLink 实现波浪动画效果
- 论坛源码推荐(4月28日):列表项目的波浪效果 兼容iOS 6与iOS 7的自定义导航条
- Xamarin.ios 下拉刷新效果
- iOS实现波浪效果
- ios view与view间切换的动画效果
- 实现类似 iOS 5 推送通知效果的代码例子
- iOS实现跑马灯效果
- Leaves -- iOS上一种图书翻页效果的实现
- ios iphone 圆角效果
- 实现类似 iOS 5 推送通知效果的代码例子
- ios中view的动画效果
- ios 视图切换动画效果