问题 重新定位合法标签(MKAttributionLabel)


我想将Legal标签移到右侧。在iOS 6和7上,下面的解决方案工作正常,但在iOS 8.3上似乎无法正常工作。

我得到了标签,然后带了一个计时器(0.1秒) viewDidLayoutSubviews 我称之为这种方法:

-(void)moveLegalLabel
{
    UIView * legalLink = [self attributionView];
    legalLink.frame = CGRectMake(self.mapView.frame.size.width - legalLink.frame.size.width - 10, self.mapView.frame.size.height - legalLink.frame.size.height - 10 , legalLink.frame.size.width, legalLink.frame.size.height);
    legalLink.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
}

适用于旋转等。 但是一旦我滚动地图,标签就会跳回到左边。 试图在这个方法中调用此方法 regionDidChangeAnimated 但是标签首先向左跳,然后向右跳,这真的很烦人......

我怎么能强迫那个愚蠢的标签留在右边?

Christian建议的解决方案: 

  1. 子类MKMapView
  2. 移动 moveLegalLabel 代码在那里
  3. 打电话给 layoutSubviews

-(void)layoutSubviews { [super layoutSubviews]; [self moveLegalLabel]; }


1392
2018-06-09 14:59


起源

为什么你会以0.1延迟的方式做到这一点? - Christian Schnorr
@ChristianSchnorr因为我需要在旋转后保留右侧的标签。主要问题是每个区域更改后标记的地图重新定位... - Templar
那么你在旋转之后如何挂钩(但没有延迟!)并撤消地图所做的任何事情? - Christian Schnorr
@ChristianSchnorr这就是我正在做的事情,但正如我所说的那样,无论有没有延迟,这都很好。问题是当我更改地图的区域(滚动/缩放地图)时,地图重新定位了愚蠢的标签。并且moveLegalLabel在regionDidChangeAnimated 随机工作。有时它会使标签保持正确,有时不会...... - Templar
那是因为用来定位它的钩子是错误的。尝试对地图进行子类化并覆盖 -layoutSubviews。 - Christian Schnorr


答案:


像钩子一样 -viewDidAppear:-mapView:regionWillChangeAnimated: 要么 -mapView:regionDidChangeAnimated:和其他人一样,不适合这个目的。

你最好的选择是子类 MKMapView 并将您的标签布局 -layoutSubviews   调用 super


2
2018-06-25 15:46





您需要它在viewDidAppear和两个MKMapViewDelegate方法中。如果你没有把它放在两个委托方法中,你将获得你所看到的跳跃。就这样!

-(void)viewDidAppear:(BOOL)animated
{
    [self moveLegalLabel];
}

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    [self moveLegalLabel];
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [self moveLegalLabel];
}

-(void)moveLegalLabel
{
    UIView * legalLink = [self.map.subviews objectAtIndex:1];
    legalLink.frame = CGRectMake(self.map.frame.size.width - legalLink.frame.size.width - 10, self.map.frame.size.height - legalLink.frame.size.height - 10 , legalLink.frame.size.width, legalLink.frame.size.height);
    legalLink.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
}

8
2018-06-17 20:24



它有点好,但它仍然随机跳跃......随着 regionWillChangeAnimated 实际上,标签保持在右侧 而 我移动地图,这很好。但在那之后 regionDidChangeAnimated soemtimes工作,有时随机跳回... - Templar
嗯我在iOS 8上在模拟器上进行测试,它运行正常。你是否在其他任何地方重新定位标签? - Erik
不......我甚至评论过它 viewDidLoad。你有什么模拟器? 8.3? - Templar
我在所有模拟器和8.3设备上测试过,问题仍然存在。它适用于30%的案例。 - Templar


您必须在viewDidAppear中加载代码,然后才能执行代码。显然你的代码是在视图准备好之前编译的。

-(void)moveLegalLabel
{
    UIView * legalLink = _mapView.subviews[1];
    legalLink.frame = CGRectMake(self.mapView.frame.size.width - legalLink.frame.size.width - 10, self.mapView.frame.size.height - legalLink.frame.size.height - 10 , legalLink.frame.size.width, legalLink.frame.size.height);
    legalLink.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
}


-(void)viewDidAppear:(BOOL)animated {
    [self moveLegalLabel];
}

如果您创建一个按钮并将代码放入其操作中,则单击时可以看到标签移动。


1
2018-06-17 21:27





尝试使用 transform 这条路:

- (void)moveLegalLabel
{
    UIView *legalLink = [self attributionView];
    legalLink.transform = CGTransformMakeTranslation(self.mapView.frame.size.width - CGRectGetMaxX(legalLink.frame) - CGRectGetMinX(legalLink.frame), self.mapView.frame.size.height - CGRectGetMaxY(legalLink.frame) - CGRectGetMinY(legalLink.frame));
}

如果没有工作尝试使用 layer.transform

- (void)moveLegalLabel
{
    UIView *legalLink = [self attributionView];
    legalLink.layer.transform = CATransform3DMakeTranslation(self.mapView.frame.size.width - CGRectGetMaxX(legalLink.frame) - CGRectGetMinX(legalLink.frame), self.mapView.frame.size.height - CGRectGetMaxY(legalLink.frame) - CGRectGetMinY(legalLink.frame));
}

1
2018-06-20 20:46



根本不工作。 - Templar


在这里,我将它从底部移到顶部:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    // Move legal notice since covered in design
    mapView.subviews
        .first { "\(type(of: $0))" == "MKAttributionLabel" }?
        .frame.origin.y = mapView.frame.minY + 10
}

0
2018-02-15 15:44





要解决此问题,您可以:

1.创建子类(MKMapView)

class CustomMapView: MKMapView {

}

2.Override layouSubviews像这样:

override func layoutSubviews() {
        super.layoutSubviews()
        let legalLabel: UIView = self.subviews[1]
        let frame = .....
    }

这种方式适合我


0
2018-04-25 13:04





一个Swift 4的例子:

  • 在iOS 11上工作

  • 不需要子类

(根据Erik的回答)

func viewDidAppear(_ animated: Bool) {
   moveLegalLabel()
}

func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
   moveLegalLabel()
}

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
   moveLegalLabel()
}

func moveLegalLabel() {
   let legalLabel: UIView = mapView.subviews[1]
   legalLabel.frame=CGRect(x: mapView.frame.size.width - (legalLabel.frame.size.width ?? 0.0) - 10, y: mapView.frame.size.height - (legalLabel.frame.size.height ?? 0.0) - 10, width: legalLabel.frame.size.width ?? 0.0, height: legalLabel.frame.size.height ?? 0.0)
}

0
2017-07-26 08:51