表视图单元格中的iOS地图视图帧原点错误

表视图单元格中的iOS地图视图帧原点错误,ios,iphone,cocoa-touch,uikit,Ios,Iphone,Cocoa Touch,Uikit,我需要在表格视图单元格中设置地图视图的位置。我只是用cellForRow方法设置框架 有些地图视图放错地方了。当我向上滚动表格并向下滚动使其重新出现以重用表格单元格时,它是固定的 注 y位置错误,但x位置正确 我用同样的方法简单地设置帧来设置图片的位置,它们总是正确的。因此,问题在于贴图视图本身,而不是如何定位帧 下面的屏幕截图显示了3个地图视图,中间的一个有一个错误的y位置 编辑: UI部分相当复杂。在cellForRowAtIndexPath方法中,我将MessageCell出列并使用Mes

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

有些地图视图放错地方了。当我向上滚动表格并向下滚动使其重新出现以重用表格单元格时,它是固定的

y位置错误,但x位置正确

我用同样的方法简单地设置帧来设置图片的位置,它们总是正确的。因此,问题在于贴图视图本身,而不是如何定位帧

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

编辑:

UI部分相当复杂。在cellForRowAtIndexPath方法中,我将MessageCell出列并使用Message:Message*Message方法调用其setupWithMessage,然后检查消息是否为location类型:location类型消息具有可选的文本视图和映射视图

        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方法,坐标正确:

编辑3:size1 size2和frame的值

方法1:CellForRowatineXpath中的alloc init UITableViewCell

简单的解决方案是cell=[[UITableViewCell alloc]init];alloc 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:从SuperView中移除

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

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

            [subview removeFromSuperview];
        }


    }
方法1:CellForRowatineXpath中的alloc init UITableViewCell

简单的解决方案是cell=[[UITableViewCell alloc]init];alloc 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:从SuperView中移除

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

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

            [subview removeFromSuperview];
        }


    }
代码示例

多重映射

多重映射

希望您能得到帮助。

代码示例

多重映射

多重映射


希望您能获得帮助。

请确保您的文本视图框架为0。如果地图视图没有显示在准确的位置,您还可以尝试以下操作

+ (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;
}

另外,请确保使用-cgloattableview:UITableView*tableView heightsforrowAtIndexPath:NSIndexPath*indexPath相应地更新单元格的高度。请确保您的textView框架为0。如果地图视图没有显示在准确的位置,您还可以尝试以下操作

+ (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;
}

另外,请确保使用-cgloattableview:UITableView*tableView heightsforrowatindexpath:NSIndexPath*indexPath相应地更新单元格的高度。我提出的解决方案实际上不是一个解决方案,而是一个备选方案

您可以从map视图创建快照,而不是将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];
}];

顺便说一句,快照代码仅适用于ios 7。如果您需要ios6或更早版本的支持,您需要进行一些cg编码

我提出的解决方案实际上不是一种解决方案,而是一种替代方案

您可以从map视图创建快照,而不是将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];
}];

顺便说一句,快照代码仅适用于ios 7。如果您需要ios6或更早版本的支持,您需要进行一点cg编码

能否将代码张贴在设置帧的位置?您使用的是哪种UITableViewCell?。通常对于这样的事情,我会在故事板上创建一个自定义单元格,创建UItableViewCell的子类,并将所有内容链接在一起。例如,我为插入PickerViews而工作。这是一个简单的视图可重用性问题。要在这里给您一个提示,请查看第一个单元格的可见部分&中间单元格上的贴图位置。如果您是通过故事板或自定义视图使用代码,请发布代码并告知我们。此外,您的自动布局和自动调整大小蒙版的使用可能也有一些问题。你用的是哪一个?@VinnyCoyne我发布了代码你可以把代码发布在你设置帧的地方吗?你用的是哪种UITableViewCell?。通常对于这样的事情,我会在故事板上创建一个自定义单元格,创建UItableViewCell的子类,并将所有内容链接在一起。例如,我为插入PickerViews而工作。这是一个简单的视图可重用性问题。要在这里给您一个提示,请查看第一个单元格的可见部分&中间单元格上的贴图位置。如果您是通过故事板或自定义视图使用代码,请发布代码并告知我们。此外,您的自动布局和自动调整大小蒙版的使用可能也有一些问题。你用的是哪一个?@VinnyCoyne我用不可重复使用的cel发布了代码

ls不是合适的方法,因为它是一个聊天应用程序,因此可能有很多手机,每个单元格可能包含富媒体,当alloc和dealloc@OMGPOP-您是否使用仪器测量了性能-我已在我的应用程序中进行了测试-我没有性能问题,即使在性能问题持续存在之后,方法2仍需要在该环境中应用-不起作用。如果我不重用单元格,所有地图坐标都放错了位置。使用不可重用的单元格不是合适的方法,因为它是一个聊天应用程序,因此可能有很多单元格,每个单元格可能包含富媒体,当alloc和dealloc@OMGPOP-您是否使用仪器测量了性能-我已在我的应用程序中进行了测试-我没有性能问题,即使在性能问题持续存在之后,方法2仍需要在该环境中应用-不起作用。如果我不重复使用单元格,所有的地图坐标都放错地方了。我不这么认为@omgpop您只需创建一个地图视图并在cellForRow中设置框架。我也用cellForRow中的Message调用setupWithMessage。谢谢,但您需要先检查一下。。bcz I在地图上没有任何问题@我不这么认为@omgpop您只需创建一个地图视图并在cellForRow中设置框架。我也用cellForRow中的Message调用setupWithMessage。谢谢,但您需要先检查一下。。bcz I在地图上没有任何问题@omgpop两个都不工作。请注意,正确的图像信息是按钮图像。如果有帮助的话?你能发布你从CGRect frame1=[self-adjustContentView:textView size:textViewSize entity:entity]获得的帧吗;CGRect frame2=[self-adjustContentView:extraView大小:extraViewSize实体:实体];我在问题中添加了调试器屏幕截图。对于所有索引路径,帧保持不变。是的,所有单元格都具有相同的帧,包括正确的帧和不正确的帧。两者都不工作。请注意,正确的图像信息是按钮图像。如果有帮助的话?你能发布你从CGRect frame1=[self-adjustContentView:textView size:textViewSize entity:entity]获得的帧吗;CGRect frame2=[self-adjustContentView:extraView大小:extraViewSize实体:实体];我在问题中添加了一个调试器屏幕截图,对于所有索引路径,框架保持不变,对吗?是的,所有单元格都具有相同的框架,包括正确的和不正确的框架