微信开发者工具高分屏

2018-11-27 20:14:29 hst_gogogo 阅读数 1063

一、创建一个小程序项目

1、下载安装微信web开发者工具,目前最新版本是1.02.1811141。

2、打开,扫码登录,

3、选择小程序项目

4、点击项目管理旁边的+

5、如果你有小程序账号会有一个APPID,详情见小程序简易教程申请账号那一节,如果还没有,可以点击下方的“小程序”使用测试号,选好项目目录,输入项目名称,初学者建议勾选点击确定然后进入IDE,在项目目录下就会生成如下右图所示的文件:

二、IDE

开发微信小程序开发工具可以用小程序开发者工具,也可以用Sublime(轻便)或WebStorm(更能全而且强大)。本节介绍小程序开发者工具。

默认模拟器、编辑器和调试器都是选中状态,界面如下:

在Help中可以快速打开帮助文档

编译代码可以点击编译图标,也可以快捷键 ctrl+s

在左上方可以选择模拟的机子和网络环境等

三、相关文件及其作用:

一开始的目录结构(如果没勾选“建立普通快速启动模板”则这里是没有目录和文件的,点击上方的"+"创建)如下图所示,下面说说每个目录及文件的作用:

一个小程序其实是由描述整体的app(唯一)和描述各个页面的page(可以是多个)组成,描述整体的app放在根目录下,由三个文件组成(包括 app.js、app.json、app.wxss,其中前两者是必需有的);小程序页面由四个文件组成(包括XXX.js、XXX.wxml、XXX.json、XXX.wxss,其中前两者必需有)注意:为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。当描述整体的样式表和描述某个页面的样式表发生冲突时,采用就近原则---即以描述某个页面的样式表为准,这在后面会举例细说。

app.json文件用于对小程序进行整体(全局)配置,在这里配置了页面文件的路径、窗口表现、网络超时时间、多tab等信息,下表是简易教程(对每个配置项都有详细的讲解,可以点进去看一下,我再写只会更加多余)中对其配置项的列举:

app.json 配置项列表

属性 类型 必填 描述 支持版本
pages String Array 页面路径列表  
window Object 全局的默认窗口表现  
tabBar Object 底部 tab 栏的表现  
networkTimeout Object 网络超时时间  
debug Boolean 是否开启 debug 模式,默认关闭  
functionalPages Boolean 是否启用插件功能页,默认关闭 2.1.0
subpackages Object Array 分包结构配置 1.7.3
workers String Worker 代码放置的目录 1.9.90
requiredBackgroundModes String Array 需要在后台使用的能力,如「音乐播放」  
plugins Object 使用到的插件 1.9.6
preloadRule Object 分包预下载规则 2.3.0
resizable Boolean iPad 小程序是否支持屏幕旋转,默认关闭 2.3.0
navigateToMiniProgramAppIdList String Array 需要跳转的小程序列表,详见 wx.navigateToMiniProgram 2.4.0
usingComponents Object 全局自定义组件配置,开发者工具 1.02.1810190 及以上版本支持此字段  

project.config.json是小程序根目录下的一个工具配置文件,这里放的是针对开发者喜好而做的一些个性化配置,如:界面颜色、编译配置、上传代码时自动压缩等,当换一台电脑或重装工具的时候,只要载入对应小程序项目的这个这个文件,开发者工具就会自动帮我们恢复到开发这个项目时候的个性化配置。

page.json是pages/logs 目录下的 logs.json这类和小程序页面相关的页面配置文件,也就是说,我们也已在 app.json中配置整个页面的整体风格(如色调等),在page.json中配置某一个页面所特有的属性(比如,一些页面允许下拉刷新,而另一些不允许,那就要单独在page.json中配置;又如:我的整个小程序的色调都是橙色,在某一个页面我想弄成紫色,那这时候就要为这个页面单独配置了)当有页面的配置项时,就会覆盖app.json中相同的配置项,如果没有指定的配置项,则在该页面中使用app.json中的配置。

wxml模板:在网页编程中,采用的是HTML+CSS+JS的组合,HTML描述的是整个页面的骨架,CSS描述页面的外观,JS描述页面的行为(负责与用户进行交互),在小程序中,XXX.wxml就充当了HTML的角色,看下面这段代码:

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>

WXML代码和HTML代码都有元素(标签)、文本(标签里面的内容)、属性(如src、class、bindtap等),那么它们有什么不同之处呢?

① 标签名不一样

如<view>相当于HTML 中的<div>,<image>相当于HTML 中的<img>等,这些要靠学习和实践的过程中慢慢地积累!更多组件请参考简易教程中的 小程序的能力

②文件结构不一样

HTML文件主要由<html><head></head><body></body></html>组成,HTML的元数据、引入CSS文件或JS文件都是在<head></head>中,<body></body>中放的是文档的所有内容(比如文本、超链接、图像、表格和列表等);而WXML中默认的根节点为<page></page>(这种说法可能不太恰当,只是我觉得方便理解,其实page是wxml的页面构造器),并且不用在WXML文件中引用CSS文件和JS文件。

③WXML中多了一些诸如wx:if 这样的属性以及 {{ }} 这样的表达式

(下面这段话引用自微信小程序的简易教程)

在网页的一般开发流程中,我们通常会通过 JS 操作 DOM (对应 HTML 的描述产生的树),以引起界面的一些变化响应用户的行为。例如,用户点击某个按钮的时候,JS 会记录一些状态到 JS 变量里边,同时通过 DOM API 操控 DOM 的属性或者行为,进而引起界面一些变化。当项目越来越大的时候,你的代码会充斥着非常多的界面交互逻辑和程序的各种状态变量,显然这不是一个很好的开发模式,因此就有了 MVVM 的开发模式(例如 React, Vue),提倡把渲染和逻辑分离。简单来说就是不要再让 JS 直接操控 DOM,JS 只需要管理状态即可,然后再通过一种模板语法来描述状态和界面结构的关系即可。

小程序的框架也是用到了这个思路,如果你需要把一个 Hello World 的字符串显示在界面上。

WXML 是这么写 :

<text>{{msg}}</text>

JS 只需要管理状态即可:

this.setData({ msg: "Hello World" })

通过 {{ }} 的语法把一个变量绑定到界面上,我们称为数据绑定。仅仅通过数据绑定还不够完整的描述状态和界面的关系,
还需要 if/else, for等控制能力,在小程序里边,这些控制能力都用 wx: 开头的属性来表达。

更详细的文档可以参考 WXML

wxss样式:wxss和css非常相似,但小程序的wxss做了一些扩充和修改,并且wxss并不是支持css的所有特性的。

①新增了尺寸单位rpx,在写CSS样式的时候需要考虑到手机设备的屏幕会有不同的宽度和设备像素比,采用一些技巧来换算一些像素单位,但如果用rpx,换算工作交给小程序底层去完成即可,它会自适应不同手机屏幕大小(换算采用的浮点数运算,所以运算结果会和预期结果有一点点偏差)


屏幕尺寸:屏幕对角线的距离;

DPI: 每英寸包含的像素点数(px);

px指的不是物理像素,而是手机中的物理分辨率,可以理解为一个点,与长度无关,点是没有大小的;

pt逻辑分辨率(视觉上看到的),与屏幕尺寸有关,可以理解为长度单位(其实与移动设备的栅格渲染有关),1pt可以由1px构成,也可以由两个或多个px组成;

ppi(pixels per inch)所表示的是每英寸长度所能够排列的像素(pixel)的数目。因此PPI数值越高,即代表显示屏能够以更高的密度显示图像。当然,显示的密度越高,拟真度就越高。pixels per inch是图像分辨率的单位,图像ppi值越高,单位面积的像素数量就越多,所以画面的细节就越丰富。

Reader指的是每个pt中包含了多少px,如iPhone6下2个px才构成1个pt,这就是为什么模拟器下iPhone6的分辨率是375而设计图一般给750像素;

视网膜屏:分辨率超过人眼识别极限的高分辨率屏幕(单位像素密度下,像素个数达到肉眼可见的极限,再多也不会更加清晰)

视网膜(Retina)屏幕是苹果公司"发明"的一个营销术语。并在部分移动产品使用。苹果这个术语用在iphone 4手机上,自此一直沿用,它将960×640的像素压缩到一个3.5英寸的显示屏内。也就是说,该屏幕的像素密度达到326像素/英寸(ppi),称之为"视网膜屏幕"。

rpx会自适应不同分辨率的设备

  • 以iPhone6的物理像素750*1334为视觉稿进行设计,而在小程序中使用rpx为单位
  • iPhone6(@2x) 下 1px = 1rpx =0.5pt   //以iPhone6的尺寸---750像素的宽做效果图,如果效果图的宽为200px,那么在小程序中就应当用100px或200rpx
  • 使用rpx时小程序会自动在不同的分辨率下进行转换,而使用px则不能;

upsampling(上采样)  图片来源:知乎


②提供了全局样式和局部样式(与app.json和page.json中的配置一个意思,不再赘述)

③只支持css的部分选择器,详见 WXSS

JS主要用于和用户进行交互(如效应用户的点击、获取用户的位置等),在小程序中也是通过编写JS脚本文件来处理用户的操作(参考 WXML - 事件)、调用API以引用微信提供的能力(本地存储、微信支付等,参考小程序的API)。

<view>{{ clk }}</view>
<button bindtap="clickMe">Please Click Me</button>

当用户点击 button 按钮的时候,我们希望把界面上 clk 显示成 "Hello World",于是我们在 button 上声明一个属性: bindtap ,在 app.js里声明 clickMe 方法来响应这次点击操作:

Page({
  clickMe: function() {
    this.setData({ clk: "Hello World" })
  }
})

app.js是小程序的脚本文件,可以在这里放监听并处理小程序的声明周期函数、声明全局变量等的脚本;

index.js是页面脚本文件,在这里放监听并处理页面的生命周期、获取小程序实例、声明并处理数据、响应页面交互事件等的脚本。

不过index.js和logs.js的角色区别,我还没明白,等弄明白了再回来更新吧

index和logs其实是两个不同的页面,index.js和logs.js的作用其实都是一样的,这个从Quickstar项目可以看出来,当我们点击头像,就会跳转到“查看启动日志”页面,这里同样为之定义了相应的页面逻辑和样式,然后有个“返回”图标,点击返回到启动页面。同理,如果要多加一个页面,在index和logs(名字是自己定的,目录下面四个文件名字一致即可)同级目录上新建对应的目录即可。

四、小程序的启动过程(基本摘自API文档,,API文档hin重要啊!没事多翻翻)

在微信客户端打开小程序前,先把整个小程序的代码下载到本地,然后通过app.json中的pages字段(对应的是页面路径组成的数组)找到小程序中所有相关页面的路径,如下面这个配置说明在 QuickStart 项目定义了两个页面(分别为pages/index/目录下的以index为名的文件 和 在pages/logs/目录下的以logs为名的文件) pages 字段的第一个页面即为小程序的首页(打开小程序首先会看到的页面),客户端把小程序首页代码装载进来后通过底层机制渲染出首页页面,

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ]
}

小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行(整个小程序只有一个 App 实例,是全部页面共享的,参考 注册程序 App ):

App({
  onLaunch: function () {
    // 小程序启动之后 触发
  }
})

程序与页面
你可以观察到 pages/logs/logs 下其实是包括了4种文件的,微信客户端会先根据 logs.json 配置生成一个界面,顶部的颜色和文字你都可以在这个 json 文件里边定义好。紧接着客户端就会装载这个页面的 WXML 结构和 WXSS 样式。最后客户端会装载 logs.js,你可以看到 logs.js 的大体内容就是:

Page({
  data: { // 参与页面渲染的数据
    logs: []
  },
  onLoad: function () {
    // 页面渲染后 执行
  }
})

Page 是一个页面构造器,这个构造器就生成了一个页面。在生成页面的时候,小程序框架会把 data 数据和 index.wxml 一起渲染出最终的结构,于是就得到了你看到的小程序的样子。

在渲染完界面之后,页面实例就会收到一个 onLoad 的回调,你可以在这个回调处理你的逻辑。

持续更新ing..

参考资料:

小程序API文档:https://developers.weixin.qq.com/miniprogram/dev/api/

360百科:https://baike.so.com/doc/955943-1010512.html

简书:https://www.jianshu.com/p/a292c6277e12

 

上一篇:初始小程序

下一篇:小程序静态启动页面的制作

2018-10-18 14:59:33 weixin_33836223 阅读数 21

一、搭建项目

官网教程:http://mpvue.com/mpvue/#_2
用vue-cli构建项目后,在微信开发者工具中项目目录选择构建的dist目录,不是src目录

二、新建页面

每一个页面都是新建文件夹,然后包含由下面三个文件
srcpagesindexindex.vue
srcpagesindexmain.js
srcpagesindexmain.json(非必须)
推荐将每个文件夹中的index.vue文件名改为模块文件名例如login.vue,在main.js中修改引入文件名即可。
文件创建好以后要到srcapp.json中进行注册。

三、mpvue引入sass

安装sass-loader:npm i sass-loader node-sass --save-dev即可
在style标签加上scss标签即可 <style scoped lang=scss>

那么如何在mpvue中引入全局sass样式

在src/main.js中
import './assets/css/global.scss';

四、表单控件

h5的select、checkbox、radio都要用微信原生组件来代替(官方文档也有写:http://mpvue.com/mpvue/#_14
需要注意的是:一些组件不支持v-model绑定,如checkbox-group,可以通过绑定change事件来更新数据

五、组件通讯

1、子组件向父组件传递数据
子组件在方法中触发:

<button @onclik="subClick">
subClick () {
    this.$emit('postResult', {result: value});
}

父组件监听事件:

<subComponent @postResult="父组件处理方法"></subComponent>

2、父组件调用子组件的方法
父组件向子组件传递参数: mpvue使用的是vue的父子组件通讯,通过输入参数props即可。
父组件调用子组件方法:
在child标签加入ref属性<child ref="child"></child>,
父组件通过this.$refs.child.childMethod()来调用子组件方法。
需要注意的是,只有在子组件渲染完以后才能调用
3、通过vuex来通讯
新建store.js,然后分别在父子组件中import

4、设置全局参数
如果我要在所有页面共享数据呢
srcmain.js中

import store from './utils/store';
Vue.prototype.$store = store;

然后在各个页面中直接this.$store.data即可
5、兄弟组件之间,通过event bus传参
新建messenger.js,然后分别在两个组件中import

发送事件组件:

messenger.$emit('msg', params);

接收事件组件:

create(){
    messenger.$on('msg', params => {});
}



五、http请求

mpvue的请求要使用微信小程序的原生请求,content-type 会被默认为 application/json,在使用post请求的时候,如果后端需要的是form-data格式,需要修改content-type为application/x-www-form-urlencoded。

对于初次开发的朋友,第一次发请求会报一个错误
http://xxxx.xxxx.xxx不在以下 request 合法域名列表中,请参考文档:不在以下 request 合法域名列表中
clipboard.png
解决方法:
微信小程序左上角菜单栏-设置
clipboard.png

微信小程序request官方文档:https://developers.weixin.qq....

六、引入ui框架

mpvue开发微信小程序引入ui框架,微信有原生的WeUI:https://weui.io/很简洁,满足更多需求还是选择第三方的ui框架。
现在github start比较多的是iview的和zanui的微信ui组件,iview有2000+的start,zanui有6000+的start,用下来比较确实是iview好用一些。
https://github.com/TalkingDat...
https://github.com/youzan/zan...(好用的是这个)
引入的时候注意,将代码一定粘贴到根目录下的static目录,不然会报错。

同时第三方组件有使用es6,需要在项目设置上

clipboard.png

七、其它坑

1、微信开发者工具,win10点击不到input,获取不到焦点。点击错位,才能获取焦点。

问题原因:因为高分屏,win10的ui做了缩放,默认150%

解决办法:将桌面缩放改成100%就行了。

本文章会持续跟新,发现问题请多多指正

2019-07-28 12:29:00 aozhi7108 阅读数 264

Windows10笔记本上运行微信小程序开发者工具,输入框(input,textarea)没有焦点,只能在真机调试,效率太低。
后来发现是Window10对笔记本高分屏支持不好,要DPI缩放,导致兼容性问题。
解决方法:

    1. 显示设置缩放与布局改为100%。这样就可以点击输入框了,但是字体变得很小,最好是外接显示器。
    2. 不修改DPI缩放,长按输入框即可!

转载于:https://www.cnblogs.com/ycwu314/p/11258489.html

2017-07-07 14:47:26 byc233518 阅读数 3264

上次是重装了解决了卡顿的问题;

总不能过几天就重装一次啊!

更不能忍受现在这样一点一卡, 一键一卡!

找遍菜单也没找到任何有用的选项!

开始解决:

0. 关闭微信web开发者工具;

1. 打开 finder, 按下 shift + command + G , 输入 ~/资源库


2. 找到 下面几个文件夹, 删掉这几个东西:

    Application Support --> 微信web开发者工具
   Preferences -->com.tencent.wechat.devtools.plist
   Caches -->微信web开发者工具

3. 重新打开吧

2016-02-26 12:12:38 haiooh 阅读数 13798

1.iPhone尺寸规格

设备

iPhone

Width

Height

对角线

Diagonal

逻辑分辨率(point)

Scale Factor

设备分辨率(pixel)

PPI

3GS

2.4 inches (62.1 mm)

4.5 inches (115.5 mm)

3.5-inch

 

320x480

@1x

320x480

163

4(s)

2.31 inches (58.6 mm)

4.5 inches (115.2 mm)

3.5-inch

320x480

@2x

640x960

326

5c

2.33 inches (59.2 mm)

4.90 inches (124.4 mm)

4-inch

320x568

@2x

640x1136

326

5(s)

2.31 inches (58.6 mm)

4.87 inches (123.8 mm)

4-inch

320x568

@2x

640x1136

326

6

2.64 inches (67.0 mm)

5.44 inches (138.1 mm)

4.7-inch

375x667

@2x

750x1334

326

6+

3.06 inches (77.8 mm)

6.22 inches (158.1 mm)

5.5-inch

414x736

@3x

(1242x2208->)

1080x1920

401 

苹果iPhone6s/iPhone6s Plus:
主屏尺⼨寸
4.7英⼨寸主屏材质Retina HD

主屏分辨率1334x750

像素屏幕像素密度326ppi

屏幕技术3D Touch 

技术窄边框4.29mm

屏幕占⽐比65.62%


iPhone 6s plus:主屏尺⼨寸5.5英⼨寸

主屏材质Retina HD

屏分辨率1920x1080

像素屏幕像素密度401ppi

屏幕技术3D Touch 

技术窄边框4.71mm

屏幕占⽐比67.67% 


2.单位inch(英吋

    1 inch = 2.54cm = 25.4mm

3.iPhone手机宽高

    上表中的宽高(width/height)为手机的物理尺寸,包括显示屏和边框。

    以下为iPhone4s的宽高示意图:


4.屏幕尺寸

    我们通常所说的iPhone5屏幕尺寸为4英寸、iPhone6屏幕尺寸为4.7英寸,指的是显示屏对角线的长度(diagonal)。

    以下为iPhone5~6+的屏幕尺寸规格示意图:


5.像素密度PPI

    PPI(Pixel Per Inch by diagonal):表示沿着对角线,每英寸所拥有的像素(Pixel)数目。

    PPI数值越高,代表显示屏能够以越高的密度显示图像,即通常所说的分辨率越高、颗粒感越弱。



    根据勾股定理,可以得知iPhone4(s)的PPI计算公式为:


    计算结果稍有出入,这是因为像素的离散采样有锯齿效应。

6.缩放因子scale factor between logic point and device pixel)

    (1)Scale起源

    早期的iPhone3GS的屏幕分辨率是320*480(PPI=163),iOS绘制图形(CGPoint/CGSize/CGRect)均以point为单位(measured in points):

    1 point = 1 pixel(Point Per Inch=Pixel Per Inch=PPI)

    后来在iPhone4中,同样大小(3.5 inch)的屏幕采用了Retina显示技术,横、纵向方向像素密度都被放大到2倍,像素分辨率提高到(320x2)x(480x2)= 960x640(PPI=326), 显像分辨率提升至iPhone3GS的4倍(1个Point被渲染成1个2x2的像素矩阵)。

    但是对于开发者来说,iOS绘制图形的API依然沿袭point(pt,注意区分印刷行业的“磅”)为单位。在同样的逻辑坐标系下(320x480):

    1 point = scale*pixel(在iPhone4~6中,缩放因子scale=2;在iPhone6+中,缩放因子scale=3)。

    可以理解为:

    scale=绝对长度比point/pixel)=单位长度内的数量比pixel/point)

    (2)UIScreen.scale

    UIScreen.h中定义了该属性:

    // The natural scale factor associated with the screen.(read-only)

    @property(nonatomic,readonlyCGFloat scale  NS_AVAILABLE_IOS(4_0);

    --------------------------------------------------------------------------------

    This value reflects the scale factor needed to convert from the default logical coordinate space into the device coordinate space of this screen.

    The default logical coordinate space is measured using points. For standard-resolution displays, the scale factor is 1.0 and one point equals one pixel. For Retina displays, the scale factor is 2.0 and one point is represented by four pixels.

    --------------------------------------------------------------------------------

    为了自动适应分辨率,系统会根据设备实际分辨率,自动给UIScreen.scale赋值,该属性对开发者只读。

    (3)UIScreen.nativeScale

    iOS8新增了nativeScale属性:

    // Native scale factor of the physical screen

    @property(nonatomic,readonlyCGFloat nativeScale NS_AVAILABLE_IOS(8_0);

    以下是iPhone6+下的输出,初步看来nativeScale与scale没有太大区别

    --------------------------------------------------------------------------------

        (lldb)p (CGFloat)[[UIScreen mainScreen] scale]
        (CGFloat) $1 = 3
        (lldb) p(CGFloat)[[UIScreen mainScreen] nativeScale]
        (CGFloat) $2 = 3

    --------------------------------------------------------------------------------

    (4)机型判别

    在同样的逻辑分辨率下,可以通过scale参数识别是iPhone3GS还是iPhone4(s)。以下基于nativeScale参数,定义了探测机型是否为iPhone6+的宏:

    --------------------------------------------------------------------------------

    // not UIUserInterfaceIdiomPad
    #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
    // detect iPhone6 Plus based on its native scale
    #define IS_IPHONE_6PLUS (IS_IPHONE && [[UIScreenmainScreen] nativeScale] == 3.0f)

    --------------------------------------------------------------------------------

    那么,同样的分辨率和scale,如何区分机型iPhone4与4s、iPhone5与5s呢?通过[[UIDevice currentDevice] model]只能判别iPhone、iPad、iPod大类,要判断iPhone具体机型型号,则需要通过sysctlbyname("hw.machine")获取详细的设备参数信息予以甄别。

7.Resolutions &Rendering



8.@2x/@3x以及高倍图适配

    (1)@2x

    @2x means the same “double”retina resolution that we’veseen on all iOS devices with retina displays to date, where each virtual pointin the user interface is represented by two physical pixels on thedisplay in each dimension, horizontal and vertical.

    iPhone3GS时代,我们为一个应用提供图标(或按钮提供贴图),只需要icon.png。针对现在的iPhone4~6 Retina显示屏,需要制作额外的@2x高分辨率版本。

    例如在iPhone3GS中,scale=1,用的图标是50x50pixel(logicalimage.size=50x50point);在iPhone4~6中,scale=2,则需要100×100pixel(logical image.size=50x50point,乘以image.scale=dimensions in pixels),并且命名为icon@2x.png。

    如果APP要同时兼容iPhone3GS~iPhone6,则需要提供icon.png/icon@2x.png两种分辨率的图片。

    (2)@3x

    @3x means a new “triple” retina resolution, where eachuser interface point is represented by three display pixels. A single @2x pointis a 2 × 2 square of 4 pixels; an @3x point is a 3 × 3 square of 9 pixels.”

    iPhone6+在实际渲染时,downsampling/1.15(1242x2208->1080x1920),准确的讲,应该是@2.46x。苹果为方便开发者用的是@3x的素材,然后再缩放到@2.46x上。

    参考:《为什么iPhone 6 Plus要将3x渲染的2208x1242分辨率缩小到1080p屏幕上?》《详解 iPhone 6 Plus 的奇葩分辨率》《iPhone 6 Plus屏幕分辨率

    如果APP要同时兼容iPhone3GS~iPhone6+,则需要提供icon.png/icon@2x.png/icon@3x.png三种分辨率的图片。

    需要注意的是,iOS APP图标的尺寸命名都需要遵守相关规范。

    (3)高倍图文件命名

    对于iPhone3、4/5/6、6+三类机型,需要按分辨率提供相应的高倍图并且文件名添加相应后缀,否则会拉伸(stretchable/resizable)失真(模糊或边角出现锯齿)。
    以下基于UIImage的两类初始化API简介高倍图的适配:
    <1>+imageNamed:该方法使用系统缓存,适合表视图重复加载图像的情形。同时该API根据UIScreen的scale,自动查找包含对应高倍图后缀名(@2x)的文件,如果没找到设置默认image.scale=1.0。因此,使用该方法,无需特意指定高倍图后缀。在实际运行时,系统如果发现当前设备是Retina屏(scale=2),会自动寻找"*@2x.png"命名格式的图片,加载针对Retina屏的图片素材,否则会失真。
    <2>+imageWithContentsOfFile/+imageWithData:(scale:)/-initWithContentsOfFile:/-initWithData:(scale:)
    这组方法创建的UIImage对象没有使用系统缓存,并且指定文件名必须包含明确的高倍图后缀。如果文件名包含@2x后缀,则image.scale=2.0;否则默认image.scale=1.0,同样对于Retina屏将会失真。
    <3>目前,适配iPhone6+时,除了一些铺满全屏的大图(LogoIcon、LaunchImage)需提供三倍图,其他的小图仍可沿用原有的二倍图自适应拉伸。

9.Screen Bounds Application Frame

    (1)UIScreen.bounds

    // Bounds of entire screen in points(本地坐标系,起点为[0,0]

    @property(nonatomic,readonlyCGRect bounds

    --------------------------------------------------------------------------------

    //考虑转屏的影响,按照实际屏幕方向UIDeviceOrientation)的宽高

    #define SCREEN_WIDTH ([UIScreenmainScreen].bounds.size.width)

    #define SCREEN_HEIGHT ([UIScreenmainScreen].bounds.size.height)

    #define STATUSBAR_HEIGHT ([UIApplicationsharedApplication].statusBarFrame.size.height)

    //不考虑转屏的影响,只取竖屏UIDeviceOrientationPortrait)的宽高

    #define SCREEN_WIDTH MIN([UIScreenmainScreen].bounds.size.width, [UIScreenmainScreen].bounds.size.height)

    #define SCREEN_HEIGHT MAX([UIScreenmainScreen].bounds.size.height, [UIScreenmainScreen].bounds.size.width)

    #define STATUSBAR_HEIGHT MIN([UIApplicationsharedApplication].statusBarFrame.size.width, [UIApplicationsharedApplication].statusBarFrame.size.height)

    --------------------------------------------------------------------------------

     (2)UIScreen.nativeBounds

    iOS8新增了nativeBounds属性,输出竖屏像素级分辨率:

    // The bounding rectangle of the physical screen,measured in pixels. (read-only)
    // This rectangle is based on the device in a portrait-up orientation. This value does not change as the device rotates.

    @property(nonatomic,readonlyCGRect nativeBounds NS_AVAILABLE_IOS(8_0);

    以下是iPhone6+下的输出:

    --------------------------------------------------------------------------------

       (lldb) poNSStringFromCGRect([(UIScreen*)[UIScreen mainScreen] bounds])
        {{0, 0}, {414, 736}}
        (lldb) poNSStringFromCGRect([(UIScreen*)[UIScreen mainScreen] nativeBounds])
        {{0, 0}, {1242, 2208}}

    --------------------------------------------------------------------------------

    (3)UIScreen.applicationFrame

    // Frame of application screen area in points (i.e.entire screen minus status bar if visible)

    // bounds除去系统状态栏

    @property(nonatomic,readonlyCGRect applicationFrame

    --------------------------------------------------------------------------------

    // APPFRAME_WIDTH=SCREEN_WIDTH

    #define APPFRAME_WIDTH ([UIScreen mainScreen].applicationFrame.size.width)

    // APPFRAME_HEIGHT=SCREEN_HEIGHT-STATUSBAR_HEIGHT

    //注意:横屏UIDeviceOrientationLandscape)时,iOS8默认隐藏状态栏,此时APPFRAME_HEIGHT=SCREEN_HEIGHT

    #define APPFRAME_HEIGHT ([UIScreen mainScreen].applicationFrame.size.height)

    -------------------------------------------------------------------------------- 

    (4)bounds和frame的区别

    下图展示了bounds和frame的区别



10.机型尺寸适配Screen Scale Adaption

    从iPhone3GS/iPhone4(s)过渡到iPhone5(s)时,在逻辑上宽度不变高度稍高,之前旧的素材和布局通过AutoresizingFlexible简单适配即可运行得很好,但由于高宽比增大,上下两端出现黑粗边(典型如LaunchImage)。从分辨率的角度来看,除了需要提供LaunchImage这种满屏图,其他基本沿用二倍图(@2x);从屏幕尺寸角度来看,需要对纵向排版略加调整。

    从iPhone5(s)发展到iPhone6(+),由于高宽比保持不变,iOS对图标、图片、字体进行等比放大自适应,清晰度会有所降低。同时,绝对坐标布局会导致在大屏下出现偏左偏上的问题。从分辨率的角度来看,iPhone6沿用二倍图(@2x),但需为iPhone6+提供更高的三倍图(@3x);从屏幕尺寸角度来看,需要重新对UI元素尺寸和布局进行适配,以期视觉协调。

    (1)按宽度适配

    我们先来看一下iPhone4~6(+)的屏幕高宽比:

       iPhone4(s):分辨率960*640,高宽比1.5
       iPhone5(s):分辨率1136*640,高宽比1.775
       iPhone6:分辨率1334*750,高宽比1.779
       iPhone6+:分辨率1920*1080,高宽比1.778
    可粗略认为iPhone5(s)、6(+)的高宽比是一致的(16:9),即可以等比例缩放。因此可以按宽度适配
        fitScreenWidth= width*(SCREEN_WIDTH/320)
    这样,共有iPhone3/4/5、6、6+三组宽度,在iPhone6、6+下将按比例横向放大。

    (2)按高度适配

    在同样的宽度下,iPhone4(s)的屏高比iPhone5(s)低,若纵向排版紧张,可以iPhone5(s)为基准,按高度适配
        fitScreenHeight= height*(SCREEN_HEIGHT/568)
    共有iPhone3/4、5、6、6+四组高度,在iPhone3/4下将按比例纵向缩小,在iPhone6、6+下将按比例纵向放大。

    这里需要注意iPhone/iOS双环上网的热点栏对纵向布局的影响:iPhone作为个人热点且有连接时,系统状态栏下面会多一行热点连接提示栏"Personal Hotspot: * Connection",纵向会下压20pt,[UIApplication sharedApplication].statusBarFrame高度变为40pt;当所有连接都断开时,热点栏消失,纵向高度恢复正常20pt。详情可参考《iPhone/iOS开启个人热点的纵向适配小结》。

    (3)按字体适配

    另外,iPhone的【设置】【通用】【辅助功能】中可以设置调节【更大字体】,APP也可以按字号适配
    例如适配表视图(UITableView:UIScrollView),无法左右滑动,因此无论字号缩放比例多大,横向都不应超过SCREEN_WIDTH。注意限定控件元素内容区域宽度以及间距,并设置适当的LineBreakMode。表视图支持上下滑动,因此纵向上的表格行高和内容区域高度可按字号缩放。

    对于纵向也不支持滑动的视图,在屏幕可见视区内排版时,最好不要随字号缩放,否则可能超出既定宽高。

11.UI相对布局

    考虑到iPhone机型的多样性,不可能针对iPhone4(s)、5(s)、6、6+四种屏幕尺寸出四套视觉交互稿,也不要基于某一机型从上往下、从左往右给绝对标注,而应该关注subView在superView中的相对位置(EdgeInsets/Frame/Center)以及siblingView之间的偏移(Offset),尽量给出适合Autolayout的相对布局比例(理想情况是只给百分比)。假如交互按照iPhone5(s)下绝对标注,则在iPhone4(s)上可能挤出屏幕底部,而在iPhone6(+)上则可能横向偏左或纵向偏上。

    开发人员基于与屏幕边缘的间距(Margin/EdgeInsets),定位边缘处的控件(钉钉子)作为参照,然后基于控件尺寸和间隙进行相对计算排版。这样,若钉子移动,相邻控件将顺向偏移,不会因为局部调整而出现凌乱

    苹果在WWDC2012 iOS6中就已提出了Auto Layout的概念,即使用约束条件来定义视图的位置和尺寸,以适应不同尺寸和分辨率的屏幕。

12.DEPRECATED API适配

    最后,除了对屏幕尺寸和分辨率进行适配之外,还需对iOS SDK中相关的DEPRECATED API进行适配。典型的如:

    (1)UILineBreakMode->NSLineBreakMode
    (2)UITextAlignment->NSTextAlignment
    (3)sizeWithFont:->boundingRectWithSize:
    (4)stretchableImageWithLeftCapWidth:topCapHeight:->resizableImageWithCapInsets:

    (5)...


参考:

iOS设备的屏幕尺寸、分辨率及其屏幕边长比例
iOS判断设备屏幕尺寸、分辨率
iOS8中的UIScreen
Detecting iPhone 6/6+ screen sizes in point values
iOS8已出,@3x图让我们何去何从?
在Xcode 6中用矢量化PDF(vectorized PDF)来支持各种尺寸的iPhone
iOS8适配须知
适配iOS8备忘录
《iOS界面适配()()()》
iPhone 6/6+适配心得
iOS8/Xcode6/iPhone6(+)适配
APP适配iOS8,iPhone6(+)截图简要说明
按比例快速兼容适配iPhone6/6 Plus
iOS的APP如何适应iPhone 5s/6/6+三种屏幕的尺寸?

微信公众平台开发

阅读数 21116