表格视图中的iOS地图视图错误框架原点

时间:2014-03-24 17:38:50

标签: ios iphone cocoa-touch uikit

我需要在表格视图单元格中设置地图视图的位置。我只是在cellForRow方法中设置框架。

某些地图视图放错了地方。当我向上滚动表格并向下滚动以重新出现(重复使用表格单元格)时,它就会被修复。

注意

  1. y位置错误但x位置正确。

  2. 我使用相同的方法(只需设置框架)来设置图片位置,它们始终是正确的。所以问题是地图视图本身而不是如何定位框架。

  3. 以下屏幕截图显示了3个地图视图,中间的一个具有错误的y位置

    enter image description here

    编辑:

    UI部分非常复杂。在cellForRowAtIndexPath方法中,我将MessageCell出列并调用其setupWithMessage:(Message *)消息方法,然后检查消息是否为类型位置:(位置类型消息具有可选的文本视图和地图视图)

            self.textView.hidden = NO;
            self.mapView.hidden = NO;
    
            self.textView.text = message.text;
    
    
            [Helper setupMapView:self.mapView posx:message.posx posy:message.posy];
    
            CGSize size1 = [UIHelper sizeWithText:message.text entity:message];
            CGSize size2 = [UIHelper sizeWithMapEntity:message];
    
            CGRect frame = [UIHelper adjustTextView:self.textView textViewSize:size1 extraView:self.mapView extraViewSize:size2 entity:message];
    
    
    
    
    
    
    
    
    + (CGRect)adjustTextView:(UITextView *)textView textViewSize:(CGSize)textViewSize extraView:(UIView *)extraView extraViewSize:(CGSize)extraViewSize entity:(id)entity {
    
    
        if (textView == nil || extraView == nil || CGSizeEqualToSize(textViewSize, CGSizeZero) || CGSizeEqualToSize(extraViewSize, CGSizeZero)) {
            CGSize targetSize;
            UIView *targetView;
    
            if (textView == nil || CGSizeEqualToSize(textViewSize, CGSizeZero)) {
    
                targetView = extraView;
                targetSize = extraViewSize;
    
            }
            else {
                targetView = textView;
                targetSize = textViewSize;
            }
    
            return [self adjustContentView:targetView size:targetSize entity:entity];
    
        }
    
        else {
    
            CGRect frame1 = [self adjustContentView:textView size:textViewSize entity:entity];
            CGRect frame2 = [self adjustContentView:extraView size:extraViewSize entity:entity];
    
            frame2.origin.y += frame1.size.height + OFFSET_BETWEEN_TEXTVIEW_EXTRAVIEW;
            extraView.frame = frame2;
    
            return CGRectMake(frame1.origin.x, frame1.origin.y, MAX(frame1.size.width, frame2.size.width), frame1.size.height + frame2.size.height + OFFSET_BETWEEN_TEXTVIEW_EXTRAVIEW);
        }
    

    请注意,上面的“extraView”可以引用文本视图下方的任何视图,例如UIImageView

    + (CGRect)adjustContentView:(UIView *)contentView size:(CGSize) size entity:(id)entity {
    
        float photoSideOffset = 60;
        float topOffset = 30;
    
        CGRect frame;
        frame.origin.y = topOffset;
        frame.size = size;
    
        if ([DBHelper isMyEntity:entity]) {
            frame.origin.x = 320 - size.width - photoSideOffset;
        }
        else {
            frame.origin.x = photoSideOffset;
        }
        contentView.frame = frame;
    
    
        if ([contentView isKindOfClass:[UITextView class]]) {
            [(UITextView *)contentView sizeToFit];
        }
    
        return contentView.frame;
    }
    

    编辑2:我对照片信息使用相同的UIHelper方法,坐标是正确的:

    enter image description here

    编辑3:size1 size2和frame

    的值

    enter image description here

4 个答案:

答案 0 :(得分:3)

方法1:cellForRowAtIndexPath

中分配init UITableViewCell

简单的解决方案是每次都cell = [[UITableViewCell alloc]init];分配init (每次都会创建新的单元格而不是缓存/或重用)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

        // Configure the cell...

       /*
        if (cell == nil) {

            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

        }

       */
      // Try below code

      cell = [[UITableViewCell alloc]init];


        ------

        -------

        return cell;

    }

方法2: removeFromSuperView

  for (UIView *subview in self.view.subviews) {

        if ([subview isKindOfClass:[UIButton class]]) { // set kind as per your own requirement

            [subview removeFromSuperview];
        }


    }

答案 1 :(得分:2)

我建议的解决方法并非真正的解决方案"但是"替代"

您可以从地图视图中创建快照,而不是将mkmapview放入单元格。然后,您可以为地图单元格创建图像单元格。我的建议是,当用户点击图像单元格并推送一个新的" MapViewController"模态。

        self.textView.hidden = NO;
        self.thumbnailButton.hidden = NO;

        self.textView.text = message.text;


        [Helper setupMapSnapshotThumbnailButton:self.thumbnailButton withPosx:message.posx posy:message.posy size:MESSAGE_SIZE_MAP];

        CGSize size1 = [UIHelper sizeWithText:message.text entity:message];
        CGSize size2 = MESSAGE_SIZE_MAP;

        CGRect frame = [UIHelper adjustTextView:self.textView textViewSize:size1 extraView:self.thumbnailButton extraViewSize:size2 entity:message];

        [self setupCommonOutletsWithContentFrame:frame];

您可以使用

创建图像
MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init];
options.scale = [UIScreen mainScreen].scale;
options.region = [self private_mapRegionWithPosx:posx posy:posy];
options.size = size;

MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options];
[snapshotter startWithCompletionHandler:^(MKMapSnapshot *snapshot, NSError *error) {
    [thumbnailButton setBackgroundImage:snapshot.image forState:UIControlStateNormal];
}];

btw快照代码仅适用于ios 7.如果你需要ios6或更早版本的支持,你需要做一些cg编码

答案 2 :(得分:1)

代码示例

<强> MultiMap.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface MultiMap : UIViewController
<UITableViewDelegate,UITableViewDataSource,MKMapViewDelegate>
{
    MKMapView *mapView;
}
@property (retain, nonatomic) IBOutlet UITableView *mainTableView;

@end

<强> MultiMap.m

#import "MultiMap.h"

@interface MultiMap ()

@end

@implementation MultiMap

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:YES];
    self.title=@"Multi Map";
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    return nil;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 200;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 4;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"multi";
    UITableViewCell *cell=nil;

    cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    mapView=[[MKMapView alloc]initWithFrame:CGRectMake(25, 25, 275, 150)];
    mapView.delegate=self;
    [mapView setBackgroundColor:[UIColor whiteColor]];
    [mapView setTintColor:[UIColor whiteColor]];

    [cell addSubview:mapView];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

}

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{

}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    MKAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@""];

    annotationView.canShowCallout = YES;

    return annotationView;
}

- (void)dealloc {
    [_mainTableView release];
    [super dealloc];
}
@end

愿你得到帮助..

答案 3 :(得分:1)

请确保textView框架为0.对于mapView未在准确位置显示的情况,您可以尝试跟进。

+ (CGRect)adjustTextView:(UITextView *)textView textViewSize:(CGSize)textViewSize extraView:(UIView *)extraView extraViewSize:(CGSize)extraViewSize entity:(id)entity {


    if (textView == nil || extraView == nil || CGSizeEqualToSize(textViewSize, CGSizeZero) || CGSizeEqualToSize(extraViewSize, CGSizeZero)) {
        CGSize targetSize;
        UIView *targetView;

        if (textView == nil || CGSizeEqualToSize(textViewSize, CGSizeZero)) {

            targetView = extraView;
            targetSize = extraViewSize;

        }
        else {
            targetView = textView;
            targetSize = textViewSize;
        }

        return [self adjustContentView:targetView size:targetSize entity:entity];

    }

    else {

        CGRect frame1 = [self adjustContentView:textView size:textViewSize entity:entity];
        CGRect frame2 = [self adjustContentView:extraView size:extraViewSize entity:entity];

        frame2.origin.y += frame1.size.height + OFFSET_BETWEEN_TEXTVIEW_EXTRAVIEW;
        extraView.frame = frame2;
        [[extraView superview] setNeedsLayout]; //Addition
        return CGRectMake(frame1.origin.x, frame1.origin.y, MAX(frame1.size.width, frame2.size.width), frame1.size.height + frame2.size.height + OFFSET_BETWEEN_TEXTVIEW_EXTRAVIEW);
    }

更新或者您可以更新以下内容

+ (CGRect)adjustContentView:(UIView *)contentView size:(CGSize) size entity:(id)entity {

float photoSideOffset = 60;
float topOffset = 30;

CGRect frame;
frame.size = size;

if ([DBHelper isMyEntity:entity]) {
    frame.origin.x = 320 - size.width - photoSideOffset;
}
else
{
    frame.origin.x = photoSideOffset;
}

for (id view in [[contentView superview] subviews])
{
    if (view != contentView)
    {
        if ([view respondsToSelector:@selector(frame)])
        {
            topOffset = (([view frame].origin.y + [view frame].size.height)<topOffset)?([view frame].origin.y + [view frame].size.height):topOffset;
        }
    }
}
if ((int)topOffset != 30)
{
    topOffset += OFFSET_BETWEEN_TEXTVIEW_EXTRAVIEW;
}
frame.origin.y = topOffset;
contentView.frame = frame;


if ([contentView isKindOfClass:[UITextView class]]) {
    [(UITextView *)contentView sizeToFit];
}

return contentView.frame;
}

还要确保使用- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

相应地更新单元格的高度