如何ios 获取屏幕点击坐标uiview 相对于屏幕的坐标

iphoneUI控件(99)
在很多时候,我们需要去计算一个UIView相对屏幕的坐标,来实现一些UI效果。
在这个UIView未被嵌套多层的时候,相对屏幕的坐标很好算,只需要精准的拿到每层superview变量去计算。
但是很多情况下,我们的UIView可能嵌套了很多层(我在项目中遇到的相对Controller.view就有6层之多),并且被嵌套在UIScrollView或者UITableView中,这个时候不可能去拿到每一层嵌套的superview的变量去计算。
基于这个需求,我写了一个通用的方法,可以很方便的拿到任意一个UIView相对屏幕的坐标。
代码虽然很简单,但是还是蛮实用的。
+ (CGRect)relativeFrameForScreenWithView:(UIView *)v
BOOL iOS7 = [[[UIDevice currentDevice] systemVersion] floatValue] &= 7
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height
if (!iOS7) {
screenHeight -= 20
UIView *view = v
CGFloat x = .0
CGFloat y = .0
while (view.frame.size.width != 320 || view.frame.size.height != screenHeight) {
x += view.frame.origin.x
y += view.frame.origin.y
view = view.superview
if ([view isKindOfClass:[UIScrollView class]]) {
x -= ((UIScrollView *) view).contentOffset.x
y -= ((UIScrollView *) view).contentOffset.y
return CGRectMake(x, y, v.frame.size.width, v.frame.size.height)
CGRect frame = [view convertRect:view.bounds toView:nil];
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:390284次
积分:7181
积分:7181
排名:第2432名
原创:354篇
转载:73篇
评论:23条
(1)(1)(1)(2)(2)(3)(2)(5)(4)(4)(1)(2)(2)(1)(1)(2)(1)(2)(2)(2)(1)(3)(5)(11)(1)(25)(259)(58)(24)IOS开发之绝对布局和相对布局(屏幕适配) - 简书
IOS开发之绝对布局和相对布局(屏幕适配)
网址:/kf/492.html
之前如果做过Web前端页面的小伙伴们,看到绝对定位和相对定位并不陌生,并且使用起来也挺方便。在IOS的UI设计中也有绝对定位和相对定位,和我们的web前端的绝对定位和相对定位有所不同但又有相似之处。下面会结合两个小demo来学习一下我们IOS开发中UI的绝对定位和相对定位。在前面的博客中所用到的UI事例用的全是绝对定位,用我们Storyboard拖拽出来的控件全是绝对定位的,就是我们可以同改变组件的frame来改变组件的位置和大小。而相对定位则不同,相对定位是参考组件周围的元素来确定组件的大小或位置,相对定位即约束和周围组件的距离来布局的,即layoutConstraint. 在布局中LayoutConstraint和Fram布局方式是不能并存的。上面说了这么多了,可能说的不太明白,还是那句话,怎么能少的了代码和实例的支持呢,下面会通过屏幕适配的事例来用绝对布局和相对布局同时实现下面的描述效果。我们要实现的效果:当上面的view的大小及位置改变时,为了不覆盖掉下面的view,我们同时要改变下view的位置。 或者说在我们4.0寸正常显示的内容,在3.5寸屏上也能正常显示,即通常我们所说的屏幕的适配。为了便于观察效果,我们可以用Slider控件来动态的改变上面view的大小,观察下面view的位置变化,下面是我们要实现的效果图:1.用绝对布局来实现上述效果,为了节省我们代码编写的时间,上面的控件是通过storyborad来实现的,然后在对应的ViewController里添加组件和控件回调的方法,主要是在slider滑动的时候来获取slider的值,然后动态的设置上面View的frame坐标(当然,如果让view往四周扩展得计算一下新的fram的值,然后动态的修改),上面的view位置和大小改变了,那么下面的view不能被上面的覆盖掉,所以也得修改blackView的fram的值。这种通过修改frame的值的方式来确定组件位置即为绝对布局下面是由storyboard拖拽过来的属性://把最上边的view拖拽到我们的代码中@property (strong, nonatomic) IBOutlet UIView *myV//添加slider@property (strong, nonatomic) IBOutlet UISlider *myS//添加下面黑色的view@property (strong, nonatomic) IBOutlet UIView *blackV下面是当slider的值改变时要回调的方法://当slider的值改变的时候回调的方法- (IBAction)sliderFunction:(id)sender{//获取slider的当前值(在storyboard设置的范围为0-120)double value = self.mySlider.//获取myView的位置CGRect frame = self.myView.//根据slider的值动态的设置myView的坐标和宽高,设置的时候view中心不变frame.origin.x =
120-frame.origin.y = 66 * (1-value/120);frame.size.height = 320-frame.origin.x*2;frame.size.width = 320-frame.origin.x*2;//更新myView的位置self.myView.frame =//同时改变下面黑色view的坐标CGRect bf = self.blackView.bf.origin.y = frame.size.height + frame.origin.y + 30;self.blackView.frame =}2.上面是我们的绝对布局的方式,接下来要学习一下相对布局的方式。相对布局使用起来会比绝对布局要复杂一些,下面先做屏幕适配的例子,图一是在iPhone的4.0寸的效果图, 当我们不做任何处理的时候在3.5寸屏上是显示不出来的如第二张图:(1)我们如何让在3.5寸屏上也显示正常呢,接下啦就是相对布局出出场的时候了,我们用相对布局的方式把最下面的view的位置改为相对于主视图的底部和左边的像素值固定,同时设置slider的位置相对于下面的view的位置相对固定。也就是下面的veiw的位置改变,则上面的slider的位置也会改变,用storyboard修改如下:(第一张图是修改最下面view的相对位置,第二张图是设置我们slider为相对布局) ,不需要在ViewController中添加任何动态吗我们就可以实现屏幕的适配。(2)那么我如何用相对布局实现上面那种view放大的效果呢,接下来我们需要新建一个工程,因为相对布局和绝对布局在同一个组件中无法并存。在新建工程中用storyboard把我们用到的控件进行拖拽 ,界面和上面的是一样的。(1)首先给我们最上面的View设置相对布局的属性,如下面的图一(2)
再给黑色的View设置相对布局的属性,入下面的图二所示:(3) 设置上面两个View相对中心对齐,选中上面的View,按着Ctrl往下面的View中拖拽,在弹出的框中选中Center X入图三(4).给我们相应的组件在storyboard中添加上约束以后,怎样来动态的改变最上面view的宽和高的约束范围呢?(即改变水平约束和垂直约束的值)第一部就得把最上面的view的水平约束和垂直约束从我们的storyboard中把最上面View中我们要用的约束拖入到我们的Viewcontroller, 第一张图是storyboard中约束所在的位置,第二张图把约束添加到ViewController中。
(5)至此我们用storyboard的工作已经做完,程序员是少不了敲代码的,也只有正儿八经的敲代码,程序员才会成长。所以喽下面就是我们在ViewController中添加的代码部分。绝对布局直接改frame的坐标值就可以啦,那么在程序中我们如何去动态的改变我们约束的值呢?下面的代码将会用到。 我们要做的事情就是在ViewController中通过改变slider的值来改变最上面View的水平约束和垂直约束,水平约束和垂直约束的相关变量我们已经拖拽过来了,下面就需要在Slider回调的方法中来改变水平和垂直约束的值。先段代码,之后在说两句。
//slider的值改变调用的方法- (IBAction)sliderChange:(id)sender{//为了避免冲突移除myView的水平和垂直约束,注意是从主视图上移除,因为约束是加载我们的主视图上,即相对于我们的主视图[self.view removeConstraint:self.widthC];[self.view removeConstraint:self.heightC];//获取slider的值double sliderValue = self.mySlider.//由slider的值重设我们的约束值,H代表水平约束, V代表垂直约束NSString *widthValue = [NSString stringWithFormat:@"H:[_myView(%lf)]", sliderValue];NSString *heightValue = [NSString stringWithFormat:@"V:[_myView(%lf)]", sliderValue];//新建约束NSArray *widthConstraint = [NSLayoutConstraint constraintsWithVisualFormat:widthValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];//给水平约束重新赋值self.widthC = widthConstraint[0];//给垂直约束重新赋值NSArray * heightConstraint = [NSLayoutConstraint constraintsWithVisualFormat:heightValue options:0 metrics:nil views:NSDictionaryOfVariableBindings(_myView)];self.heightC = heightConstraint[0];//往主视图上添加新的约束[self.view addConstraint:self.widthC];[self.view addConstraint:self.heightC];}代码说明:
1.一个组件中只能有一中约束,如在myView中我们已经有一个垂直约束,我们如果再给他添加一个垂直约束的话,那么程序在运行时就会报错,错误内容:“Unable to simultaneously satisfy constraints.……”;
2.所以在添加新的约束之前,我们得把之前加在我们组件中相应的约束给去掉;约束是加在我们对应组件的父视图上,移除也得从组件的父视图上移除;
3.在设置约束的值的时候我们是以字符串的形式把参数传递给约束的,如:H:[_myView(200)] H代表水平约束,V代表垂直约束。中括号里是我们要为那个组件添加约束以及约束的值是多少;
4.给我们的约束更新我们新建的约束
5.在把更新的约束添加到我们的父视图上,到此我们就可以实现上面我们上面用绝对布局实现的功能补充说明:
在绝对布局时我们还可以获取屏幕的尺寸,通过屏幕的尺寸来计算我们组件所在的位置,主要代码如下://获取屏幕大小UIScreen *s = [UIScreen mainScreen];//获取屏幕边界CGRect bounds = s.//获取屏幕的高度float height = bounds.size.2835人阅读
iPhone开发(62)
主要是通过setAutoresizingMask这个属性来设置;
例如:要一个button按钮始终居中显示
首先始化UIButton *btn的坐标位置(如果你想自适应,要使用相对坐标来设置btn的frame;这样开始时不管是横屏还是竖屏,获取的屏幕宽度都是当前屏幕的宽度,后面自适应属性才会正确)
btn.frame =&CGRectMake(self.frame.size.width/2-20,
0, 40,30)];//btn在屏幕中间;
& & [btn setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;//使其左右宽度都自适应即居中
& & &其效果和用IB设置的一样。
参考:例如下面的代码设置和下面图片中在IB中设置的效果是一样的:
setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin];
在 UIView 中有一个autoresizingMask的属性,它对应的是一个枚举的值(如下),属性的意思就是自动调整子控件与父控件中间的位置,宽高。
UIViewAutoresizingNone
UIViewAutoresizingFlexibleLeftMargin
UIViewAutoresizingFlexibleWidth
UIViewAutoresizingFlexibleRightMargin
UIViewAutoresizingFlexibleTopMargin
UIViewAutoresizingFlexibleHeight
UIViewAutoresizingFlexibleBottomMargin = 1 && 5
typedef NSUInteger UIViewA
分别解释以上意思。
UIViewAutoresizingNone就是不自动调整。
UIViewAutoresizingFlexibleLeftMargin就是自动调整与superView左边的距离,也就是说,与superView右边的距离不变。
UIViewAutoresizingFlexibleRightMargin就是自动调整与superView的右边距离,也就是说,与superView左边的距离不变。
UIViewAutoresizingFlexibleTopMargin
UIViewAutoresizingFlexibleBottomMargin
UIViewAutoresizingFlexibleWidth
UIViewAutoresizingFlexibleHeight
以上就不多解释了,参照上面的。
也可以多个枚举同时设置。如下:
subView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin
|UIViewAutoresizingFlexibleRightM
如果有多个,就用“|”关联。
还有一个属性就是autoresizesSubviews,此属性的意思就是,是否可以让其subviews自动进行调整,默认状态是YES,就是允许,如果设置成NO,那么subView的autoresizingMask属性失效。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:604025次
积分:5049
积分:5049
排名:第4359名
原创:46篇
转载:34篇
评论:51条
(1)(1)(1)(4)(4)(1)(1)(2)(8)(5)(3)(4)(7)(4)(4)(6)(6)(9)(8)(2)31141人阅读
Objective-C(12)
IOS 地图定位,标注地图,获取经纬度:
一、使用MKMapView 定位
二、在地图上通过经纬度标注(大头针)
项目源码:
最终效果图:
打开应用程序会自动定位并且放大到自己的位置,然后在我的位置上显示自己的经纬度,通过填写经纬度可以放置大头针标注。
一、获取自身的位置和经纬度
1、新建项目,将ios的提供位置服务和地图服务的库加入到项目中 点项目名-&Build Phases点开Link Binary With Libraries
将CoreLocation和MapKit两个库加入到项目中,前者是ios的位置服务库,后者是操作MKMapView的库
2、新建UIViewController 控件布局和设置好关系属性。导入&CoreLocation/CoreLocation.h&和&MapKit/MapKit.h&
还要让控制器类实现MKMapViewDelegate协议
#import &UIKit/UIKit.h&
#import &MapKit/MapKit.h&
#import &CoreLocation/CoreLocation.h&
@interface MainViewController : UIViewController&MKMapViewDelegate,UITextFieldDelegate&
@property (weak, nonatomic) IBOutlet UITextField *longitudeT
@property (weak, nonatomic) IBOutlet UITextField *latitudeT
@property (weak, nonatomic) IBOutlet MKMapView *mapV
//自己经度
@property (weak, nonatomic) IBOutlet UILabel *longitudeL
//自己纬度
@property (weak, nonatomic) IBOutlet UILabel *latitudeL
//放置标注Button
- (IBAction)annotationAction:(id)
3、MKMapView可以通过&setShowsUserLocation:YES这个方法来获取自己的位置,并且当地图更新自己的位置后会调用
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation的一个协议的委托方法,我要在这个方法里面试实现当地图位置更新后/获取自己位置后对地图进行放大。
首先在viewDidLoad方法里对让地图调用setShowsUserLocation方法来实现地图的定位,并且设置MapView的委托类。
- (void)viewDidLoad
//设置MapView的委托为自己
[self.mapView setDelegate:self];
//标注自身位置
[self.mapView setShowsUserLocation:YES];
[super viewDidLoad];
然后实现-(void)mapView:(MKMapView&*)mapView didUpdateUserLocation:(MKUserLocation&*)userLocation方法:
//MapView委托方法,当定位自身时调用
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
CLLocationCoordinate2D loc = [userLocation coordinate];
//放大地图到自身的经纬度位置。
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[self.mapView setRegion:region animated:YES];
CLLocationCoordinate2D 是一个结构体记录经纬度,通过地图的获取的location来给其赋值。
运行一下程序地图载入的同时获得自身的位置,并且会自动放大到你所在的位置。
调试位置:
模拟器在运行的时候,可以自定义的设置其自身所在的位置
4、获取自身的经纬度显示在两个label上,还是在-(void)mapView:(MKMapView&*)mapView
didUpdateUserLocation:(MKUserLocation&*)userLocation方法里面实现,通过MKUserLocation这个类里面有经度和纬度的属性,直接拿出来显示在label上
//MapView委托方法,当定位自身时调用
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
CLLocationCoordinate2D loc = [userLocation coordinate];
//显示到label上
self.longitudeLabel.text = [NSString stringWithFormat:@&%f&,loc.longitude];
self.latitudeLabel.text = [NSString stringWithFormat:@&%f&,loc.latitude];
//放大地图到自身的经纬度位置。
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(loc, 250, 250);
[self.mapView setRegion:region animated:YES];
二、在地图上加上标注(大头针)
1、要给地图添加标注,就要自己实现一个标注类,这个类必须实现MKAnnotation协议,MKAnnotation有个必须要定义的属性
CLLocationCoordinate2D
新建一个 MyPoint类继承自NSObject类并且实现&MKAnnotation&协议然后定义下列属性:
#import &Foundation/Foundation.h&
#import &MapKit/MapKit.h&
@interface MyPoint : NSObject &MKAnnotation&
//实现MKAnnotation协议必须要定义这个属性
@property (nonatomic,readonly) CLLocationCoordinate2D
@property (nonatomic,copy) NSString *
//初始化方法
-(id)initWithCoordinate:(CLLocationCoordinate2D)c andTitle:(NSString*)t;
在.m文件里实现init方法
#import &MyPoint.h&
@implementation MyPoint
-(id)initWithCoordinate:(CLLocationCoordinate2D)c andTitle:(NSString *)t{
self = [super init];
_coordinate =
以上就是一个简单的标注类了。
2、回到ViewController类中在button按钮关联的- (IBAction)annotationAction:(id)sender方法中实现标注:
首先通过UITextField所填写的经纬度创建一个CLLocation类,然后赋值给CLLocationCoordinate2D:
//创建CLLocation 设置经纬度
CLLocation *loc = [[CLLocation alloc]initWithLatitude:[[self.latitudeText text] floatValue] longitude:[[self.longitudeText text] floatValue]];
CLLocationCoordinate2D coord = [loc coordinate];
创建MyPoint实例最后调用MKMapView的addAnnotation方法将MyPoint的实例加入到标注中:- (IBAction)annotationAction:(id)sender中的实现:
//放置标注
- (IBAction)annotationAction:(id)sender {
//创建CLLocation 设置经纬度
CLLocation *loc = [[CLLocation alloc]initWithLatitude:[[self.latitudeText text] floatValue] longitude:[[self.longitudeText text] floatValue]];
CLLocationCoordinate2D coord = [loc coordinate];
//创建标题
NSString *titile = [NSString stringWithFormat:@&%f,%f&,coord.latitude,coord.longitude];
MyPoint *myPoint = [[MyPoint alloc] initWithCoordinate:coord andTitle:titile];
//添加标注
[self.mapView addAnnotation:myPoint];
//放大到标注的位置
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 250, 250);
[self.mapView setRegion:region animated:YES];
另外还可以使用[self.mapView addAnnotations:NSArray]这个方法,这个方法的参数是一个数组对象,可以同时给地图上添加多个标注。
3、最后运行程序填入经纬度,就能给地图加上标注了。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:913131次
积分:4446
积分:4446
排名:第5335名
原创:39篇
转载:17篇
评论:198条
(1)(1)(1)(1)(1)(3)(3)(9)(3)(4)(4)(1)(1)(1)(5)(4)(3)(3)(1)(7)}

我要回帖

更多关于 屏幕坐标获取工具 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信