08 8月

iOS应用内跳转到appstore 某个app详情页(广告常见)

iOS应用内跳转到appstore 某个app详情页(广告常见)

应用内直接跳转到appstore,需要添加StoreKit,framework系统库,需要实现下面的代理方法



- (void)skipBtnClick {
    
    SKStoreProductViewController *storeProductViewContorller = [[SKStoreProductViewController alloc] init];
    //设置代理请求为当前控制器本身
    storeProductViewContorller.delegate = self;
    //加载一个新的视图展示
    [storeProductViewContorller loadProductWithParameters:
     //appId唯一的
     @{SKStoreProductParameterITunesItemIdentifier : @"577710538"} completionBlock:^(BOOL result, NSError *error) {
         //block回调
         if(error){
             NSLog(@"error %@ with userInfo %@",error,[error userInfo]);
         }else{
             //模态弹出appstore
             [self presentViewController:storeProductViewContorller animated:YES completion:^{
                 
             }];
         }
     }];
}

代理delegate


//取消按钮监听
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController{
    [self dismissViewControllerAnimated:YES completion:^{

    }];
}

如果有不对的地方,还请您留言。转载请注明一下链接。

本文地址:http://www.laileshuo.com/?p=1243

博客地址:www.laileshuo.com www.laileshuo.cn

12 7月

IOS代码片段 类似微博发帖按钮弹簧效果

facebook POP动画引擎,实现类似微博发帖按钮弹簧效果

alt text

代码如下



- (void)show {
    
    for (UIView *subView in self.contentView.subviews) {
        if ([subView isKindOfClass:[MenuButton class]]) {
            CGRect fromRect = subView.frame;
            fromRect.origin.y = CGRectGetMaxY(self.bounds);
            subView.frame = fromRect;
        }
    }
    
    [super showAnimiation:^(BOOL finished) {
        
        NSInteger index = 0;
        for (UIView *subView in self.contentView.subviews) {
            if ([subView isKindOfClass:[MenuButton class]]) {
                MenuButton *menuButton = (MenuButton *)subView;
                double delayInSeconds = index * MenuButtonAnimationInterval;
                CGRect fromRect = menuButton.frame;
                CGRect toRect = menuButton.originFrame;

                [self initailzerAnimationWithToPostion:toRect formPostion:fromRect atView:subView beginTime:delayInSeconds];
                index++;
            }
        }
    }];
}

#pragma mark - Animation

- (void)initailzerAnimationWithToPostion:(CGRect)toRect formPostion:(CGRect)fromRect atView:(UIView *)view beginTime:(CFTimeInterval)beginTime {
    POPSpringAnimation *springAnimation = [POPSpringAnimation animation];
    springAnimation.property = [POPAnimatableProperty propertyWithName:kPOPViewFrame];
    springAnimation.removedOnCompletion = YES;
    springAnimation.beginTime = beginTime + CACurrentMediaTime();
    CGFloat springBounciness = 10 - beginTime * 2;
    //springAnimation.springBounciness = springBounciness;    // value between 0-20
    springAnimation.springBounciness = 5;    // value between 0-20
    
    CGFloat springSpeed = 12 - beginTime * 2;
    springAnimation.springSpeed = springSpeed;     // value between 0-20
    springAnimation.toValue = [NSValue valueWithCGRect:toRect];
    springAnimation.fromValue = [NSValue valueWithCGRect:fromRect];
    
    [view pop_addAnimation:springAnimation forKey:@"POPSpringAnimationKey"];
}

本文作为初学者的学习的记录,以便之后查阅。谢谢。

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=669

博客地址:www.laileshuo.com www.laileshuo.cn

12 7月

IOS代码 自带点击抖动动画BUTTON

IOS代码 自带点击抖动动画BUTTON

alt text

代码如下


#import "FlatButton.h" #import @interface FlatButton() - (void)setup; - (void)scaleToSmall; - (void)scaleAnimation; - (void)scaleToDefault; @end @implementation FlatButton + (instancetype)button { return [self buttonWithType:UIButtonTypeCustom]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } #pragma mark - Private instance methods - (void)setup { [self addTarget:self action:@selector(scaleToSmall) forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter]; [self addTarget:self action:@selector(scaleAnimation) forControlEvents:UIControlEventTouchUpInside]; [self addTarget:self action:@selector(scaleToDefault) forControlEvents:UIControlEventTouchDragExit]; } - (void)scaleToSmall { CASpringAnimation *scaleAnimation = [CASpringAnimation animationWithKeyPath:@"transform.scale.xy"]; scaleAnimation.toValue = @0.95; scaleAnimation.duration = scaleAnimation.settlingDuration; //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大 Defaults to one scaleAnimation.mass = 5; //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快 Defaults to 100 scaleAnimation.stiffness = 100; //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快 Defaults to 10 scaleAnimation.damping = 10; //初始速率,动画视图的初始速度大小 Defaults to zero //速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反 scaleAnimation.initialVelocity = 10; //估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算 NSLog(@"====%f",scaleAnimation.settlingDuration); scaleAnimation.duration = scaleAnimation.settlingDuration; //removedOnCompletion 默认为YES 为YES时,动画结束后,恢复到原来状态 //scaleAnimation.removedOnCompletion = NO; // springAnimation.fillMode = kCAFillModeBoth; [self.layer addAnimation:scaleAnimation forKey:@"layerScaleSmallAnimation"]; } - (void)scaleAnimation { CASpringAnimation *scaleAnimation = [CASpringAnimation animationWithKeyPath:@"transform.scale.xy"]; scaleAnimation.toValue = @1.0; scaleAnimation.duration = scaleAnimation.settlingDuration; //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大 Defaults to one scaleAnimation.mass = 5; //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快 Defaults to 100 scaleAnimation.stiffness = 100; //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快 Defaults to 10 scaleAnimation.damping = 10; //初始速率,动画视图的初始速度大小 Defaults to zero //速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反 scaleAnimation.initialVelocity = 10; //估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算 NSLog(@"====%f",scaleAnimation.settlingDuration); scaleAnimation.duration = scaleAnimation.settlingDuration; //removedOnCompletion 默认为YES 为YES时,动画结束后,恢复到原来状态 //scaleAnimation.removedOnCompletion = NO; // springAnimation.fillMode = kCAFillModeBoth; [self.layer addAnimation:scaleAnimation forKey:@"layerScaleSpringAnimation"]; } - (void)scaleToDefault { CASpringAnimation *scaleAnimation = [CASpringAnimation animationWithKeyPath:@"transform.scale.xy"]; scaleAnimation.toValue = @1.0; scaleAnimation.duration = scaleAnimation.settlingDuration; //质量,影响图层运动时的弹簧惯性,质量越大,弹簧拉伸和压缩的幅度越大 Defaults to one scaleAnimation.mass = 5; //刚度系数(劲度系数/弹性系数),刚度系数越大,形变产生的力就越大,运动越快 Defaults to 100 scaleAnimation.stiffness = 100; //阻尼系数,阻止弹簧伸缩的系数,阻尼系数越大,停止越快 Defaults to 10 scaleAnimation.damping = 10; //初始速率,动画视图的初始速度大小 Defaults to zero //速率为正数时,速度方向与运动方向一致,速率为负数时,速度方向与运动方向相反 scaleAnimation.initialVelocity = 10; //估算时间 返回弹簧动画到停止时的估算时间,根据当前的动画参数估算 NSLog(@"====%f",scaleAnimation.settlingDuration); scaleAnimation.duration = scaleAnimation.settlingDuration; //removedOnCompletion 默认为YES 为YES时,动画结束后,恢复到原来状态 //scaleAnimation.removedOnCompletion = NO; // springAnimation.fillMode = kCAFillModeBoth; [self.layer addAnimation:scaleAnimation forKey:@"layerScaleDefaultAnimation"]; } @end

本文作为初学者的学习的记录,以便之后查阅。谢谢。

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=1231

博客地址:www.laileshuo.com www.laileshuo.cn

11 7月

IOS代码片段 系统的时钟APP里秒表计时效果

facebook POP动画引擎,实现IOS代码片段 系统的时钟APP里秒表计时效果

alt text

代码如下


POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"countdown" initializer:^(POPMutableAnimatableProperty *prop) { prop.writeBlock = ^(id obj, const CGFloat values[]) { UILabel *lable = (UILabel*)obj; label.text = [NSString stringWithFormat:@"d:d:d",(int)values[0]/60,(int)values[0]%60,(int)(values[0]*100)0]; }; // prop.threshold = 0.01f; }]; POPBasicAnimation *anBasic = [POPBasicAnimation linearAnimation]; //秒表当然必须是线性的时间函数 anBasic.property = prop; //自定义属性 anBasic.fromValue = @(0); //从0开始 anBasic.toValue = @(3*60); //180秒 anBasic.duration = 3*60; //持续3分钟 anBasic.beginTime = CACurrentMediaTime() + 1.0f; //延迟1秒开始 [label pop_addAnimation:anBasic forKey:@"countdown"];

本文作为初学者的学习的记录,以便之后查阅。谢谢。

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=669

博客地址:www.laileshuo.com www.laileshuo.cn

11 7月

IOS代码片段 很多金融类app 数字 增加效果

很多金融类app 数字 增加效果
使用facebook POP实现

alt text


// 初始化 POPBasicAnimation *anim = [POPBasicAnimation animation]; // 限时 1s. 2s. anim.duration = 3.0; POPAnimatableProperty * prop = [POPAnimatableProperty propertyWithName:@"count++" initializer:^(POPMutableAnimatableProperty *prop) { prop.readBlock = ^(id obj, CGFloat values[]){ values[0] = [[obj description] floatValue]; }; prop.writeBlock = ^(id obj, const CGFloat values[]) { [obj setText:[NSString stringWithFormat:@"%.2f",values[0]]]; }; prop.threshold = 0.01; }]; anim.property = prop; anim.fromValue = @(0.0); anim.toValue = @(1314.52); [self.g_countLabel pop_addAnimation:anim forKey:@"counting"];

本文作为初学者的学习的记录,以便之后查阅。谢谢。

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=1224

博客地址:www.laileshuo.com www.laileshuo.cn

11 7月

Redis的基本使用(基于maven和spring)

使用redis基本测试

maven导包

  <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
  </dependency>

基本连接

public static void main(String[] args) {
// 连接本地的 Redis 服务
Jedis jedis = new Jedis(“localhost”);
System.out.println(“连接成功”);
// 查看服务是否运行
System.out.println(“服务正在运行: ” + jedis.ping());
}

存入string类型的值

public static void main(String[] args) {
// 连接本地的 Redis 服务
Jedis jedis = new Jedis(“localhost”);
//使用字符串string存值
jedis.set(“城市”, “南京”);
}

在图形化redis客户端可以看到,存值成功

alt text

string类型取值

Jedis jedis = new Jedis(“localhost”);
String city = jedis.get(“城市”);

存入list集合类型的值

public static void main(String[] args) {
// 连接本地的 Redis 服务
Jedis jedis = new Jedis(“localhost”);
//使用字符串list存值
jedis.lpush(“城市”, “南京”);
jedis.lpush(“城市”, “上海”);
jedis.lpush(“城市”, “苏州”);
jedis.lpush(“城市”, “北京”);
jedis.lpush(“城市”, “南通”);
}

图形化界面展示效果

alt text

list集合取值

public static void main(String[] args) {
// 连接本地的 Redis 服务
Jedis jedis = new Jedis(“localhost”);
//list集合取值,这里注意的是,100的位置是结束的角标,如果大了没事,小了的话就会缺
List arr = jedis.lrange(“城市”, 0, 100);
System.out.println(arr.size());
for (String string : arr) {
System.out.println(string);
}
}

存入Map的值
map类型存值又叫Redis hash ,是一个string类型的field和value的映射表

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    //Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
    //这里要求的是map必须是key和value都是string类型的
    Map<String, String> map=new HashMap<>();
    map.put("name", "小明");
    map.put("age", "13");
    map.put("sex", "男");
    map.put("height", "174");

    //调用jedis的hmset(存入hash map)的方法将map的键值对存进去
    jedis.hmset("people", map);
}

图形化客户端界面显示为:

alt text

map取值

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    //新建一个string类型的数组,用于存当时存入redis的map的key值
    String[] arr=new String[4];
    arr[0]="name";
    arr[1]="age";
    arr[2]="sex";
    arr[3]="height";
    //利用jedis的hmget方法,从数据库中依次取出对应的map的key值
    List<String> list = jedis.hmget("people",arr);
    for (int i = 0; i < arr.length; i++) {
        System.out.println("存入键值对为:"+arr[i]+"--"+list.get(i));
    }

}

结果为:

存入键值对为:name–小明
存入键值对为:age–13
存入键值对为:sex–男
存入键值对为:height–174
存入Set的值
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

存入代码:

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    //使用list存入数据
    List<String> list=new ArrayList<>();
    list.add("北京");
    list.add("南京");
    list.add("上海");
    list.add("北京");
    list.add("北京");
    list.add("上海");
    list.add("苏州");
    list.add("南京");
    //打印源数据
    System.out.println("源数据为"+list);

    //因为jedis的sadd的方法,存入的是一个数组对象或者多数据,所有将集合对象转换成数组对象
    String[] arr=new String[list.size()];
    for (int i = 0; i < arr.length; i++) {
        arr[i]=list.get(i);
    }
    //调用sadd方法存入数据库
    jedis.sadd("city", arr);

}

原来数据为:

源数据为[北京, 南京, 上海, 北京, 北京, 上海, 苏州, 南京]
redis数据库图形化客户端显示

alt text

可见,存入后,是把数据去重之后存储的.

set数据的取出

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    //调用jedis的smembers方法,获取所有的set集合
    Set<String> smembers = jedis.smembers("city");

    System.out.println(smembers);
}

控制台结果为:

[北京, 上海, 南京, 苏州]
存入sortset的值
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。

存入代码:

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    Map<String, Double> map=new HashMap<>();
    map.put("北京", 1.0);
    map.put("北京", 2.0);
    map.put("南京", 3.0);
    map.put("上海", 4.0);
    map.put("上海", 5.0);
    map.put("南京", 6.0);

    //调用jedis的zadd方法存入
    jedis.zadd("city", map);
}

图形化客户端界面:

alt text

南京在放入map时候,是在上海之前,可是最后score却取的是后面的一个.可见,如果有重复的数据产生的话,去重是将前面序号的重复去掉

取出代码:

public static void main(String[] args) {
//连接本地的jedis服务器
Jedis jedis=new Jedis(“localhost”);

    //索引在0,到10之间的,分数由高到底的取出所有的集合
    Set<String> zrevrange = jedis.zrevrange("city", 0, 10);
    System.out.println(zrevrange);

}

控制台输出:

[南京, 上海, 北京]

使用redis的基于spring测试
使用spring整合

applicationContext.xml中配置

名称空间:

xmlns:cache=”http://www.springframework.org/schema/cache”
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd”>
配置文件:




<cache:annotation-driven cache-manager="redisCacheManager" />

<!-- jedis 连接池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxIdle" value="300" />
    <property name="maxWaitMillis" value="3000" />
    <property name="testOnBorrow" value="true" />
</bean>

<!-- redis的连接工厂 -->
<bean id="connectionFactory"
    class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
    p:host-name="localhost" p:port="6379" p:pool-config-ref="poolConfig"
    p:database="0" />

<!-- spring data 提供 redis模板  -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="keySerializer">
        <bean
            class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    </property>
    <property name="valueSerializer">
        <bean
            class="org.springframework.data.redis.serializer.StringRedisSerializer">
        </bean>
    </property>
</bean>

在需要使用的service类中,使用注解

//自动注入redis模板
@Autowired
private RedisTemplate<String, String> redisTemplate;

使用spring整合string类型的值

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class RedisTest {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Test
public void Test01(){
    //通过模板,获取到String类型的redis对象
    ValueOperations<String, String> redisString = redisTemplate.opsForValue();

    //使用set方法,保存key和value的值
    redisString.set("city", "南京");

    //使用get(key)的方法获取到city对应的值
    String string = redisString.get("city");
    System.out.println(string);
}

}

图形化界面:

alt text

控制台输出:

alt text

使用spring整合list类型的值

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class RedisTest {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Test
public void Test01(){

    //通过模板获取list类型的redis
    ListOperations<String, String> redisList = redisTemplate.opsForList();

    //通过key依次插入数据
    redisList.leftPush("city", "南京");
    redisList.leftPush("city", "上海");
    redisList.leftPush("city", "北京");
    redisList.leftPush("city", "上海");
    redisList.leftPush("city", "南京");

    //查找索引范围内的所有数据
    List<String> range = redisList.range("city", 0, 10);
    System.out.println(range);

}

}

图形化客户端:

alt text

结果:

[南京, 上海, 北京, 上海, 南京]
使用spring整合Hash类型的值

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class RedisTest {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Test
public void Test01(){

    //通过模板对象,获取到redis的hash类型的对象
    HashOperations<String, Object, Object> redisMap = redisTemplate.opsForHash();

    //建立map集合
    Map<String, String> map=new HashMap<>();

    map.put("name", "小明");
    map.put("age", "18");
    map.put("length", "175");

    //存储hash对象
    redisMap.putAll("people", map);

    //获取数据库中存储的集合的key
    Set<Object> keys = redisMap.keys("people");
    //遍历key集合,获取到map中所有的value值
    for (Object key : keys) {
        Object value = redisMap.get("people", key);
        System.out.println(key+":"+value);
    }
}

}

图形化客户端界面:

alt text

取值后的控制台界面:

name:小明
length:175
age:18
使用spring整合Set类型的值
代码示例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class RedisTest {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Test
public void Test01(){
    //通过redis模板,创建set类型的redis对象
    SetOperations<String, String> redisSet = redisTemplate.opsForSet();

    //新建数组,赋值
    String[] arr=new String[5];
    arr[0]="南京";
    arr[1]="北京";
    arr[2]="南京";
    arr[3]="上海";
    arr[4]="北京";

    //调用set的add方法,存入key和数组
    redisSet.add("city", arr);

    //通过redis的获取成员方法,利用key获取到set集合
    Set<String> members = redisSet.members("city");
    System.out.println(members);

}

}

图形化数据客户端界面:

alt text

控制台界面:

[北京, 南京, 上海]
由此可见,set类型的redis不是固定顺序的.

使用spring整合sortSet类型的值
由于set类型是不具有顺序的,而sortSet类型则具有顺序

代码示例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
public class RedisTest {

@Autowired
private RedisTemplate<String, String> redisTemplate;

@Test
public void Test01(){

    //使用模板创建ZSet对象
    ZSetOperations<String, String> redisZSet = redisTemplate.opsForZSet();

    //存值,存value的同时,还加上顺序
    redisZSet.add("city", "南京", 1);
    redisZSet.add("city", "北京", 2);
    redisZSet.add("city", "上海", 3);
    redisZSet.add("city", "南京", 4);
    redisZSet.add("city", "上海", 5);
    redisZSet.add("city", "南京", 6);

    //获取范围顺序里面的值
    Set<String> rangeByScore = redisZSet.rangeByScore("city", 1, 10);
    System.out.println(rangeByScore);

}

}

图形化客户端界面:

alt text

控制台数据:

[北京, 上海, 南京]
效果同之前一样.

来源 https://www.cnblogs.com/wangxinblog/p/7349638.html

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=1220

博客地址:www.laileshuo.com www.laileshuo.cn

11 7月

IOS代码 保存视频到相册中

//IOS保存视频到相册中
- (void)saveVideoPath:(NSString *)videoPath {
    NSURL *url = [NSURL fileURLWithPath:videoPath];

    //标识保存到系统相册中的标识
    __block NSString *localIdentifier;

    //首先获取相册的集合
    PHFetchResult *collectonResuts = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
    //对获取到集合进行遍历
    [collectonResuts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        PHAssetCollection *assetCollection = obj;
        //folderName是我们写入照片的相册
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            //请求创建一个Asset
            PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
            //请求编辑相册
            PHAssetCollectionChangeRequest *collectonRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
            //为Asset创建一个占位符,放到相册编辑请求中
            PHObjectPlaceholder *placeHolder = [assetRequest placeholderForCreatedAsset];
            //相册中添加视频
            [collectonRequest addAssets:@[placeHolder]];

            localIdentifier = placeHolder.localIdentifier;
        } completionHandler:^(BOOL success, NSError *error) {
            if (success) {
                NSLog(@&quot;保存视频成功!&quot;);
            } else {
                NSLog(@&quot;保存视频失败:%@&quot;, error);
            }
        }];
        //        }
        *stop = YES;
    }];
}

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=1217

博客地址:www.laileshuo.com www.laileshuo.cn

11 7月

MySQL查询优化:连接查询排序limit(join、order by、limit语句)

MySQL查询优化:连接查询排序limit(join、order by、limit语句)

不知道有没有人碰到过这样恶心的问题:两张表连接查询并limit,SQL效率很高,
但是加上order by以后,语句的执行时间变的巨长,效率巨低。

情况是这么一个情况:现在有两张表,team表和people表,每个people属于一个
team,people中有个字段team_id。

下面给出建表语句:

[sql]

create table t_team

(

id int primary key,

tname varchar(100)

);

create table t_people

(

id int primary key,

pname varchar(100),

team_id int,

foreign key (team_id) references t_team(id)

);

下面我要连接两张表查询出前10个people,按tname排序。

于是,一个SQL语句诞生了:select * from t_people p left join t_team t onp.
team_id=t.id order by p.pname limit 10; [语句①]

这个是我第一反应写的SQL,通俗易懂,也是大多数人的第一反应。

然后来测试一下这个语句的执行时间。

首先要准备数据。我用存储过程在t_team表中生成1000条数据,在t_people表中
生成100000条数据。(存储过程在本文最后)

执行上面那条SQL语句,执行了好几次,耗时在3秒左右。

再换两个语句对比一下:

1.把order by子句去掉:select * from t_people p left join t_team t on p.team_id=
t.id limit10; [语句②]

耗时0.00秒,忽略不计。

2.还是使用order by,但是把连接t_team表去掉:select * from t_people p order
by p.pname limit 10; [语句③]

耗时0.15秒左右。

对比发现[语句①]的效率巨低。

为什么效率这么低呢。[语句②]和[语句③]执行都很快,[语句①]不过是二者的结合。
如果先执行[语句③]得到排序好的10条people结果后,再连接查询出各个people的
team,效率不会这么低。那么只有一个解释:MySQL先执行连接查询,再进行排序。

解决方法:如果想提高效率,就要修改SQL语句,让MySQL先排序取前10条再连接查询。

SQL语句:

select * from (select * from t_people p order by p.pname limit 10) p left join t_team
t on p.team_id=t.id limit 10; [语句④]

[语句④]和[语句①]功能一样,虽然有子查询,虽然看起来很别扭,但是效率提高了很多,
它的执行时间只要0.16秒左右,比之前的[语句①]提高了20倍。

这两个表的结构很简单,如果遇到复杂的表结构…我在实际开发中就碰到了这样的
问题,使用[语句①]的方式耗时80多秒,但使用[语句④]只需1秒以内。

最后给出造数据的存储过程:

[sql]

CREATE PROCEDURE createdata()

BEGIN

DECLARE i INT;

START TRANSACTION;

SET i=0;

WHILE i<1000 DO

INSERT INTO t_team VALUES(i+1,CONCAT('team',i+1));  

SET i=i+1;  

END WHILE;

SET i=0;

WHILE i<100000 DO

INSERT INTO t_people VALUES(i+1,CONCAT('people',i+1),i%1000+1);  

SET i=i+1;  

END WHILE;

COMMIT;

END

来源 https://blog.csdn.net/xiao__gui/article/details/8616224

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。谢谢。

本文地址:http://www.laileshuo.com/?p=1214

博客地址:www.laileshuo.com www.laileshuo.cn

31 5月

ios开发 3D Touch ShortcutItem

ios开发 3D Touch ShortcutItem
使用iOS 9,新款iPhone机型会在用户界面上添加3D touch。
用户现在可以按主屏幕图标立即访问您的应用程序提供的功能。

在您的应用中,用户现在可以按视图查看其他内容的预览并获得对功能的加速访问。

ApplicationShortcuts:使用UIApplicationShortcutItems,它演示主屏幕静态和动态快速操作

ViewControllerPreviews:使用UIViewController预览API(演示peek(预览)和pop(提交))以及peek快速操作

用户一直可以点击应用程序图标启动它,或者触摸并按住任何应用程序来编辑主屏幕。现在,通过按下iPhone 6s或iPhone 6s Plus上的应用程序图标,用户可以获得一组快速操作。当用户选择一个快速操作时,您的应用程序会激活或启动,您的应用程序委托对象会收到快速操作消息。

alt text

ShortcutItem静态设置,可以在info.plist中设置



UIApplicationShortcutItems
    
        
            UIApplicationShortcutItemIconType
            UIApplicationShortcutIconTypeShare
            UIApplicationShortcutItemType
            Title1
            UIApplicationShortcutItemSubtitle
            SubTitle1
            UIApplicationShortcutItemTitle
            StateTitle1
        
        
            UIApplicationShortcutItemType
            Title2
            UIApplicationShortcutItemSubtitle
            SubTitle3
            UIApplicationShortcutItemTitle
            StateTitle2
        
        
            UIApplicationShortcutItemType
            Title3
            UIApplicationShortcutItemSubtitle
            SubTitle3
            UIApplicationShortcutItemTitle
            StateTitle3
        
    

ShortcutItem动态设置,这里使用单聊实现设置即点击进入相应的页面


#import "SD3DTouchManager.h" #import "SDSessionManager.h" static SD3DTouchManager *shareInstance = nil; @implementation SD3DTouchManager + (instancetype)sharedInstance { static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ shareInstance = [[SD3DTouchManager alloc] init]; }); return shareInstance; } - (void)creat3DShortcutItem { if (IS_IOS9_OR_LATER) { UIApplicationShortcutIcon *sendIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"ic_bar_search"]; UIApplicationShortcutItem *sendItem = [[UIApplicationShortcutItem alloc]initWithType:SD_3D_WE_SEND localizedTitle:@"找代送" localizedSubtitle:nil icon:sendIcon userInfo:nil]; UIApplicationShortcutIcon *buyIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"ic_note_comment"]; UIApplicationShortcutItem *buyItem = [[UIApplicationShortcutItem alloc]initWithType:SD_3D_WE_BUY localizedTitle:@"找代买" localizedSubtitle:nil icon:buyIcon userInfo:nil]; UIApplicationShortcutIcon *rechargeIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"ic_note_tag"]; UIApplicationShortcutItem *rechargeItem = [[UIApplicationShortcutItem alloc]initWithType:SD_3D_RECHARGE localizedTitle:@"一键充值" localizedSubtitle:nil icon:rechargeIcon userInfo:nil]; UIApplicationShortcutIcon *profileIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"ic_mine"]; UIApplicationShortcutItem *profileItem = [[UIApplicationShortcutItem alloc]initWithType:SD_3D_RECHARGE localizedTitle:@"我的信息" localizedSubtitle:nil icon:profileIcon userInfo:nil]; [UIApplication sharedApplication].shortcutItems = @[sendItem,buyItem,rechargeItem,profileItem]; } } - (BOOL)application3DShortcutOptions:(NSDictionary *)launchOptions { BOOL luanched = YES; if (IS_IOS9_OR_LATER) { UIApplicationShortcutItem *shortcutItem = [launchOptions valueForKey:UIApplicationLaunchOptionsShortcutItemKey]; if (shortcutItem) { //判断设置的快捷选项标签唯一标识,根据不同标识执行不同操作 [self apply3DTouch:shortcutItem]; luanched = NO; } } return luanched; } - (void)apply3DTouch:(UIApplicationShortcutItem *)shortcutItem { if ([SDSessionManager shareInstance].isLogin) { UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController; UINavigationController *navigationController; if ([controller isKindOfClass:[UINavigationController class]]) { navigationController = (UINavigationController *)controller; } else { navigationController = controller.navigationController; } if ([shortcutItem.type isEqualToString:SD_3D_WE_SEND]) { DLog(@"3D 进入代送页面"); } else if ([shortcutItem.type isEqualToString:SD_3D_WE_BUY]) { DLog(@"3D 进入代买页面"); } else if ([shortcutItem.type isEqualToString:SD_3D_RECHARGE]) { DLog(@"3D 进入充值页面"); } else if ([shortcutItem.type isEqualToString:SD_3D_MIME_INFO]) { DLog(@"3D 进入我的信息页面"); } } } @end

performActionForShortcutItem响应方法:


#pragma mark - 3D Touch //如果APP没被杀死,还存在后台,点开Touch会调用该代理方法 - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler { if (shortcutItem) { //判断设置的快捷选项标签唯一标识,根据不同标识执行不同操作 [[SD3DTouchManager sharedInstance] apply3DTouch:shortcutItem]; } if (completionHandler) { completionHandler(YES); } } 这里进行跳转到相应的页面

效果图

alt text

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。如果有错误或不妥之处请发送邮件到lansidream@foxmail.com。谢谢。

本文地址:http://www.laileshuo.com/?p=1208

博客地址:www.laileshuo.com www.laileshuo.cn

31 5月

IOS开发 Airprint

IOS开发 Airprint

可以iPhone或iPad无线打印,需要使用支持Airprint的打印机。
打印支持三种视图:UITextView、UIWebView 和 MKMapView。

打印UIText视图内容

// 初始化输入框并设置位置和大小
 self.textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 150, [UIScreen mainScreen].bounds.size.width - 20, 260)];
 // 设置预设文本
 // 设置文本字体
 self.textView.font = [UIFont fontWithName:@&quot;Arial&quot; size:16.5f];
 // 设置文本颜色
 self.textView.textColor = [UIColor colorWithRed:51/255.0f green:51/255.0f blue:51/255.0f alpha:1.0f];
 // 设置文本框背景颜色
 self.textView.backgroundColor = [UIColor whiteColor];
 // 设置文本对齐方式
 self.textView.textAlignment = NSTextAlignmentLeft;
 // 设置自动纠错方式
 self.textView.autocorrectionType = UITextAutocorrectionTypeNo;

 //外框
 self.textView.layer.borderColor = [UIColor redColor].CGColor;
 self.textView.layer.borderWidth = 1;
 self.textView.layer.cornerRadius =5;

 self.textView.text = @&quot;三月走过柳絮散落恋人们匆匆 \n我的爱情闻风不动\n翻阅昨日仍有温度蒙尘的心事\n恍恍惚惚已经隔世\n遗憾无法说惊觉心一缩\n紧紧握着青花信物信守着承诺\n离别总在失意中度过\n记忆油膏反复涂抹无法愈合的伤口\n你的回头划伤了沉默\n那夜重逢停止漂泊你曾回来过\n相濡相忘都是疼痛\n只因昨日善良固执委屈着彼此\n打碎信物取消来世\n遗憾无法说惊觉心一缩\n紧紧握着青花信物信守着承诺\n离别总在失意中度过\n记忆油膏反复涂抹无法愈合的伤口\n你的回头划伤了沉默\n紧紧握着青花信物雕刻着寂寞\n就好像我无主的魂魄\n纠缠过往无端神伤摔碎谁也带不走\n你我一场唤不醒的梦&quot;;

点击按钮进行打印

- (void)printButtonAction {

 //生成UIPrintInfo
 UIPrintInfo *printInfo = [UIPrintInfo printInfo];
 printInfo.outputType = UIPrintInfoOutputGeneral;
 printInfo.jobName = @&quot;print demo&quot;;

 [UIPrintInteractionController sharedPrintController].printInfo = printInfo;

 //打印
 UIMarkupTextPrintFormatter *formatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:self.textView.text];
 formatter.perPageContentInsets = UIEdgeInsetsMake(10,10,10,10);
 [UIPrintInteractionController sharedPrintController].printFormatter = formatter;

 [[UIPrintInteractionController sharedPrintController] presentAnimated:YES completionHandler:^(UIPrintInteractionController * _Nonnull printInteractionController, BOOL completed, NSError * _Nullable error) {
     DLog(@&quot;error:%@&quot;,error);
 }];
}

展示的界面视图

alt text

打印任务,首先看下打印选项配置

UIPrintInteractionController呈现用户界面并管理打印

  • printInfo:之前所述的打印任务的配置。
  • printPaper:纸张类型的物理和打印尺寸的一个简单的类型描述;除了专门的应用程序,这将由 UIKit 处理。
  • showsNumberOfCopies:当值为 true 时,让用户选择拷贝的份数。
  • showsPageRange:当值为 true 时,让用户从打印源中选择一个子范围。这只在多页内容时有用,它默认关闭了图像。
  • showsPaperSelectionForLoadedPapers:当值为 true 并且所选择的打印机有多个纸张选项时,用户界面将让用户选择用于打印的纸张。

UIPrintinfo对象包含有关打印作业的信息。

该信息被分配给UIPrintInteractionController的printInfo属性。

打印一个任务
在我们看看如何格式化打印的实际内容之前,让我们先看一下配置打印任务的选项和呈现给用户的打印选项。

UIPrintInfo
打印任务细节在 UIPrintInfo 实例中设置。可以使用以下属性:

printInfo.jobName:此打印任务的名称。这个名字将被显示在设备的打印中心,对于有些打印机则显示在液晶屏上。

UIPrintInfoOrientation:// default is UIPrintInfoOrientationPortrait 如果你打印的内容有一个内置的方向值,如 PDF,这个属性将被忽略。
UIPrintInfoDuplex:// default is based on document type (none for photo, long edge for other) 的边界设置指示如何装订双面页面,而 .None 不支持双面打印(这里不是 UI 切换为双面打印,令人困惑)。
UIPrintInfoOutputType:// default is UIPrintInfoOutputGeneral 给 UIKit 提供要打印内容的类型提示。

UIPrintInfoOutputType:是一个枚举类型:

typedef NS_ENUM(NSInteger, UIPrintInfoOutputType) {

    //文本和图形混合类型;允许双面打印
    UIPrintInfoOutputGeneral,           // B&amp;W or color, normal quality output for mixed text, graphics, and images

    //彩色或黑白图像;禁用双面打印,更适用于图像媒体的纸张类型。
    UIPrintInfoOutputPhoto,             // B&amp;W or color, best quality output for images

    //如果你的内容只包括黑色文本,那么该类型比 UIPrintInfoOutputGeneral 更好。
    UIPrintInfoOutputGrayscale,         // B&amp;W content only

    //对于仅灰度的图像,根据打印机的不同,该类型可能比 .Photo 更好。
    UIPrintInfoOutputPhotoGrayscale NS_ENUM_AVAILABLE_IOS(7_0),    // B&amp;W only, best quality output for images
 } __TVOS_PROHIBITED;

UIPrintInfo 还提供一个 dictionaryRepresentation 属性,它可以被保存并用来创建一个新的 UIPrintInfo 实例。

UIPrintFormatter 打印文本可以被格式化。

UIPrintFormatter 类有两个子类可用于格式化文本UISimpleTextPrintFormatter、 UIMarkupTextPrintFormatter
UIViewPrintFormatter可以格式化三种视图:UITextView、UIWebView 和 MKMapView。

打印格式化器有几个特性,让你以不同方式定义页面的打印区域;格式化器的最终打印区域将是满足以下条件的最小矩形:

这里我们定义了打印页面的插页
用户会看到iPhone打印界面以选择打印机和打印份数

  • contentInsets:一个全部内容页面的边缘插图集合。左和右插图被应用在每一页上,但顶部边界则只应用在第一页上。底部插图将被忽略。
  • perPageContentInsets:一个每一页格式化内容页面的边缘插图集。
  • maximumContentWidth 和 maximumContentHeight:如果指定,可以进一步约束内容区域的宽度和高度。

需要注意的一点

Apple 的文档没有明确说明,但所有这些值都基于每英寸 72 点。

点击打印后

alt text

源代码

谢谢您的阅读,希望本站及文档能带给你帮助,给你带来简洁明了的阅读体验。如果有错误或不妥之处请发送邮件到lansidream@foxmail.com。谢谢。

本文地址:http://www.laileshuo.com/?p=1205

博客地址:www.laileshuo.com www.laileshuo.cn