DanijelHuis / HDAugmentedReality

Augmented Reality component for iOS, written in Swift.
MIT License
480 stars 97 forks source link

Cannot scale ARAnnotationView with CGAffineTransform #40

Closed inorganik closed 7 years ago

inorganik commented 7 years ago

I want to scale the ARAnnotationView based on distance, but haven't been successful because transforming the view doesn't work. What I tried doing was putting this inside my ARAnnotationView subclass:

    var wasScaled = false
    override func bindUi() {
        if !wasScaled {
            // normally scale would be dynamic but this is just to test
            self.transform = CGAffineTransform(scaleX: 0.5, y:0.5)
            wasScaled = true
        }
    }

I also tried putting it in the ARDataSource's ar(...) method. But wherever I put it, same problem occurs. The view appears to rapidly scale to be huge. Labels inside the view throw hundreds of warnings like ignoring bogus label size (8246085550080.000000, 10307292364845.000000) ... and this number gets bigger and bigger with each consecutive warning as I pan around.

I noticed that ARPresenter calls layoutAnnotationViews() many times per second, so I tried putting in a flag in my ARAnnotationView subclass wasScaled, and using that to conditionally call the transform statement if it's false. But even that doesn't work.

Is there any way to do this? For now I'm forced to manually scale the frame by doing calculations, which does not scale subviews.

inorganik commented 7 years ago

Update - I also tried scaling the annotation on tap like:

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        delegate?.didTouch(annotationView:self)
        UIView.animate(withDuration: 0.5) { 
            self.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
        }
    }

Even though it should be doubling the size of the annotation, it scales it down to 0 and disappears. Any idea what's causing this?

Overall I really like this lib, thanks so much!

DanijelHuis commented 7 years ago

Hi,

I am not sure what is going on, frame of each annotation view is changing very often, maybe that is the problem, but it shouldn't be. I am not doing anything special with annotation views. I'll have a look at it during the weekend.

DanijelHuis commented 7 years ago

I don't think this is related to this library, it just seems that you have to set view.transform = CGAffineTransform.identity each time before frame of that view is set, and then set your transform.

I tested it with TestAnnotationView(Demo project) by adding this:

var myTransform: CGAffineTransform = CGAffineTransform.identity
    open func tapGesture()
    {
        self.myTransform = CGAffineTransform(rotationAngle: 1)
        self.transform = self.myTransform
    }
    var oldTransform: CGAffineTransform = CGAffineTransform.identity
    override open var frame: CGRect
    {
        willSet
        {
            self.transform = CGAffineTransform.identity
        }
        didSet
        {
            self.transform = self.myTransform
        }
    }
inorganik commented 7 years ago

Thanks! Some labels get pushed around inside the view if I pan away and come back to the annotation, but that can probably be fixed with autolayout.