• iOS 第三方自定义Alertview项目MBProcessHud中的重要代码分析


    做ios,弹出一个自定义的alertview挺常见的。ios7以前,我们可以对系统的UIAlertView进行一点操作,实现一点简单的定制,但是ios7不再允许我们这样做了。因此,我们需要自己创建一个alertview。感谢大神们的辛勤工作,在网络上已经有多个效果不错的自定义alertview项目,大体分为2类:通过UIWindow实现,通过UIView实现。

    通过UIWindow实现的话,首先要创建新的UIWindow,为了实现旋转后的布局,必须加载一个rootviewcontroller,再把需要的view加载rootviewcontroller上,总体来说,实现比较复杂。

    通过UIView实现的话,可以通过addsubview 方法加到需要的view上,再实现相关动画,总体来说比较简单。

    MBProcessHud项目是第二种实现方式,网上还有一个项目对它进行了扩展,实现了更多酷炫效果,请到code4app网站或github上查询。

    MBProcessHud项目没有提供按钮选项,我们可以通过更改它的代码实现,所以在这里我简单分析一下它的关键函数。

    最主要的函数就是要重写view的- (void)layoutSubviews 函数

    - (void)layoutSubviews {
        
        // Entirely cover the parent view
        UIView *parent = self.superview;
        if (parent) {
            self.frame = parent.bounds;
        }
        CGRect bounds = self.bounds;
        
        // Determine the total widt and height needed,margin为一个常量
        CGFloat maxWidth = bounds.size.width - 4 * margin;
        //这里的totalSize大小指的是显示内容的圆角矩形的大小
        CGSize totalSize = CGSizeZero;
        
        //第一个控件---------------------------------------------
        //确定indicator的大小
        CGRect indicatorF = indicator.bounds;
        //先确定indicator的宽度,如果过大,那么设定成maxWidth,否则保持原值。
        indicatorF.size.width = MIN(indicatorF.size.width, maxWidth);
        //修正totoalSize的宽度,使它能容的下indicator
        totalSize.width = MAX(totalSize.width, indicatorF.size.width);
        //不断叠加totoalSize的高度
        totalSize.height += indicatorF.size.height;
        
        //第二个控件------------------------------------------------
        CGSize labelSize = MB_TEXTSIZE(label.text, label.font);
        labelSize.width = MIN(labelSize.width, maxWidth);
        totalSize.width = MAX(totalSize.width, labelSize.width);
        //不断叠加totoalSize的高度
        totalSize.height += labelSize.height;
        if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
            totalSize.height += kPadding;
        }
    
        //第三个控件---------------------------------------------
        CGFloat remainingHeight = bounds.size.height - totalSize.height - kPadding - 4 * margin; 
        CGSize maxSize = CGSizeMake(maxWidth, remainingHeight);
        CGSize detailsLabelSize = MB_MULTILINE_TEXTSIZE(detailsLabel.text, detailsLabel.font, maxSize, detailsLabel.lineBreakMode);
        totalSize.width = MAX(totalSize.width, detailsLabelSize.width);
        totalSize.height += detailsLabelSize.height;
        if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
            totalSize.height += kPadding;
        }
        
       
        totalSize.width += 2 * margin;
        totalSize.height += 2 * margin;
        
        // Position elements,依次放置控件
        //第一个控件-------------------------
        CGFloat yPos = round(((bounds.size.height - totalSize.height) / 2)) + margin + yOffset;
        CGFloat xPos = xOffset;
        indicatorF.origin.y = yPos;
        indicatorF.origin.x = round((bounds.size.width - indicatorF.size.width) / 2) + xPos;
        indicator.frame = indicatorF;
        //累加y偏移量
        yPos += indicatorF.size.height;
        
        if (labelSize.height > 0.f && indicatorF.size.height > 0.f) {
            yPos += kPadding;
        }
        
        //第二个控件-------------------------
        CGRect labelF;
        labelF.origin.y = yPos;
        labelF.origin.x = round((bounds.size.width - labelSize.width) / 2) + xPos;
        labelF.size = labelSize;
        label.frame = labelF;
          //累加y偏移量
        yPos += labelF.size.height;
        
        if (detailsLabelSize.height > 0.f && (indicatorF.size.height > 0.f || labelSize.height > 0.f)) {
            yPos += kPadding;
        }
        
         //第三个控件-------------------------
        CGRect detailsLabelF;
        detailsLabelF.origin.y = yPos;
        detailsLabelF.origin.x = round((bounds.size.width - detailsLabelSize.width) / 2) + xPos;
        detailsLabelF.size = detailsLabelSize;
        detailsLabel.frame = detailsLabelF;
        
        // Enforce minsize and square rules,尽量保持矩形
        if (square) {
            CGFloat max = MAX(totalSize.width, totalSize.height);
            if (max <= bounds.size.width - 2 * margin) {
                totalSize.width = max;
            }
            if (max <= bounds.size.height - 2 * margin) {
                totalSize.height = max;
            }
        }
        if (totalSize.width < minSize.width) {
            totalSize.width = minSize.width;
        } 
        if (totalSize.height < minSize.height) {
            totalSize.height = minSize.height;
        }
        
        self.size = totalSize;
    }
  • 相关阅读:
    在京东云擎上搭建自己的网站
    在新浪SAE上搭建自己的网站!
    GitHub在windows上代码管理教程
    mongodb在windows下安装教程
    nodejs在windows平台下搭建部署环境教程
    Windows下搭建PHP开发环境,整合Apache+PHP+MySQL(举例软件为32位)
    IIS7发布 EF MVC项目提示404.0页面错误解决方案
    “VS无法连接远程数据库”解决方案
    easyui的 getSelections 与 getSelected 对比区别
    Linq中int转String(解决LINQ to Entities 不识别方法"System.String ToString()",因此该方法无法转换为存储表达式.)
  • 原文地址:https://www.cnblogs.com/breezemist/p/3513348.html
Copyright © 2020-2023  润新知