• 20130829ios cocos2d下拉列表的向上弹出实现(ios开发遇到的frame的问题)


    前几天仔细区分了ios中frame,bounds,center之间的关系。

     Frame:边框矩形,是视图相对于其父坐标的位置和大小

    Bounds:边界矩形,是本地坐标系统(一般较少使用)

    Center:边框矩形的中心点。

    今天在工作中需要用到下拉列表,就参考这片文章,在自己的view中加入一个下拉列表:http://disanji.net/2011/02/20/iphone-uipickerview/。但是任务的需求是下拉列表是往上弹出而不是往下弹出,这就涉及到了frame的问题了,因为frame我没有掌握好,这个问题耽误了我三四个小时才解决。

    这个下拉列表主要由两个部分组成:一个是UITextFieldView,另一个是UITableView。我按照上面的教程把它们封装到一个继承于UIView的类:DropDownList。然后我在另外一个主view中定义了DropDownList并且把DropDownList加入到我的主view中。

    我的DropDownList类的初始化以及加入到子类中是这样实现的:

            downList=[[[DropDownList alloc]initWithFrame:CGRectMake(10, 380, 100, 25)]autorelease];
            [[[CCDirector sharedDirector]view]addSubview:downList];

    在DropDownList中另外两个控件的initwithframe初始化是这样的

    -(id)initWithFrame:(CGRect)frame
    {
        if(self=[super initWithFrame:frame]){
            //默认的下拉列表中的数据
            list=[[NSArray alloc]initWithObjects:@"1",@"2",@"3",@"4",@"saul",@"kevin",@"kely",nil];
            
            borderStyle=UITextBorderStyleRoundedRect;
            
            showList=NO; //默认不显示下拉框
            oldFrame=frame; //未下拉时控件初始大小
            //当下拉框显示时,计算出控件的大小。
            newFrame=CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height*5);
            
            lineColor=[UIColor lightGrayColor];//默认列表边框线为灰色
            listBgColor=[UIColor whiteColor];//默认列表框背景色为白色
            lineWidth=1;     //默认列表边框粗细为1
            
            //把背景色设置为透明色,否则会有一个黑色的边
            self.backgroundColor=[UIColor clearColor];
                //pushlist
        listView=[[UITableView alloc]initWithFrame:
                  CGRectMake(lineWidth,oldFrame.size.height+lineWidth,
                             oldFrame.size.width-lineWidth*2,
                             oldFrame.size.height*4-lineWidth*2)];
        listView.dataSource=self;
        listView.delegate=self;
        listView.backgroundColor=listBgColor;
        listView.separatorColor=lineColor;
        listView.hidden=!showList;//一开始listView是隐藏的,此后根据showList的值显示或隐藏
        
        [self addSubview:listView]; 
        [listView release];
        
        //textField
        textField=[[UITextField alloc]
                   initWithFrame:CGRectMake(0, 0,
                                            oldFrame.size.width,
                                            oldFrame.size.height)];
    //               initWithFrame:CGRectMake(0, oldFrame.size.height*4, oldFrame.size.width, oldFrame.size.height)];
        textField.borderStyle=borderStyle;//设置文本框的边框风格
        textField.enabled=FALSE;
        [self addSubview:textField];
        [textField addTarget:self action:@selector(dropdown) forControlEvents:UIControlEventAllTouchEvents];
            
    
            textFieldText=[[NSString alloc]init];
        }
        return self;
    }

    下面就是处理点击UITextField的代码

    -(BOOL)showList{//setShowList:No为隐藏,setShowList:Yes为显示
     returnshowList;
    }
    -(void)setShowList:(BOOL)b{
     showList=b;
     NSLog(@"showlist is set ");
     if(showList){
      self.frame=newFrame;
     }else {
      self.frame=oldFrame;
     }
     listView.hidden=!b;
    }

    我想把弹出列表从上面弹出,是改写了listview控件的初始化的区域,

    CGRectMake(lineWidth,oldFrame.size.height+lineWidth, oldFrame.size.width-lineWidth*2,oldFrame.size.height*4-lineWidth*2)];

    虽然可以向上弹出了,但是弹出的列表无法响应点击事件,后来又改了DropDownList类的initwithframe的方法,但是反而显示不正确了。然后就越改越乱,忽然想起来frame是相对于父类的位置。就仔细分析了一下。原来的无法响应点击事件是因为我的UITableView往原点的上方,超出了初始化的view的区域,所以无法响应。要想UITableView向上弹出,就得把UITableView的初始化区域定义在UITextField的上面。但是这样一来又有问题了:UITextField又不响应点击事件了,原来是我一开始定义的区域是oldFrame=frame,只有一个CGRectMake(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height)大小,而UITextField是定义在UITableView的下面,等于说在一开始初始化的时候,UITextField又跑到类DropDownList的frame外面去了。最后想起来还是动态的定义类DropDownList的frame的大小和两个控件的位置吧。

    -(void)setShowList:(BOOL)b{
        showList=b;
        NSLog(@"showlist is set ");
        if(showList){
            self.frame=newFrame;
            CGRect listFrame = CGRectMake(lineWidth,lineWidth*2,
                       oldFrame.size.width-lineWidth*2,
                       oldFrame.size.height*4-lineWidth*2);
            listView.frame=listFrame;
            CGRect textFrame =CGRectMake(0, oldFrame.size.height*4, oldFrame.size.width, oldFrame.size.height);
            textField.frame=textFrame;
        }else {
            self.frame=oldFrame;
            CGRect textFrame =CGRectMake(0, 0, oldFrame.size.width, oldFrame.size.height);
            textField.frame=textFrame;
        }
        listView.hidden=!b;
        [self setNeedsDisplay];
    }

    今天遇到的第二个问题:

    如果类中定义了一个变量,而又只写了@property,没有写@synthesize的话,我们要是通过.运算符得到其变量会得到不正确的null,这个问题也让我调试了一个小时。@@

    还有,object c中的release只是让其引用减一,而不是真正的像C++那样release掉

  • 相关阅读:
    一起谈.NET技术,.NET分布式架构开发实战之一 故事起源 狼人:
    JS替换节点
    mysql数据库的简单语句的介绍(1)
    JS对img进行操作
    POJ 1006 Biorhythms 数论(孙子定理)
    Tomcat与Jetty插件 配置根路径指定项目
    [置顶] cocos2dx 2.x版本之win32 window移植android 环境搭配 只用NDK 超级详细 android 环境搭配
    调频广播六十年
    ajax两个网页实现完美的 分页功能
    Cocos2dX数据、动作、消息的基本操作
  • 原文地址:https://www.cnblogs.com/baozou/p/3290173.html
Copyright © 2020-2023  润新知