久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

在 UIScrollView 中為 zoomScale 設置動畫時不需要的滾

Unwanted scrolling when animating zoomScale in UIScrollView(在 UIScrollView 中為 zoomScale 設置動畫時不需要的滾動)
本文介紹了在 UIScrollView 中為 zoomScale 設置動畫時不需要的滾動的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

執行摘要:有時 UIScrollView 會對 contentOffset 的值進行不必要的更改,從而導致應用程序在正在查看的文檔中顯示錯誤的位置.不需要的更改與滾動視圖的 zoomScale 的動畫更改一起發生.

詳情:UIScrollView 中使用 CATiledLayer 縮小時遇到問題.CATiledLayer 保存一個pdf,當 contentOffset 在一定范圍內時,當我縮小時, contentOffset 會改變(這是錯誤)在縮放發生之前.contentOffset 似乎在 Apple 的代碼中有所更改.

為了說明問題,我修改了 Apple 的示例應用程序 ZoomingPDFViewer.代碼在github上:https://github.com/DirkMaas/ZoomingPDFViewer-bugp>

點擊將導致 zoomScale 使用 animateWithDuration 更改為 0.5,從而縮小.如果 UIScrollViewcontentOffset.y 小于 2700 或大于 5900,則 zoomScale 動畫可以正常工作.如果在 contentOffset.y 介于這兩個值之間時發生點擊,則 contentOffset.y 將跳轉(非動畫)到大約 2700,然后是 zoomScale 動畫會發生,但滾動會同時發生,因此當動畫完成時,contentOffset.y 是它應該在的位置.但跳躍從何而來?

例如,假設點擊屏幕時 contentOffset.y 為 2000:zoomScale 動畫效果很好;contentOffset.y 沒有改變.

但是如果點擊屏幕時contentOffset.y為4000:contentOffset.y會在沒有動畫的情況下跳轉到2700左右,然后進行縮放和滾動將從該點開始并同時發生.動畫完成后,看起來好像我們從 4000 處直接放大,所以我們最終在正確的位置,但行為是錯誤的.

關于用戶界面的說明:

  • 文字可以正常垂直滾動
  • 文本可以通過正常的捏合方式放大和縮小
  • 單擊將導致 zoomScale 設置為 0.5;變化是動畫的

我注意到如果 zoomScale 大于 0.5,則跳躍不是那么大.另外,如果我使用 setZoomScale:animated: 而不是 animateWithDuration,錯誤就會消失,但我不能使用它,因為我需要鏈接動畫.

以下是我所做的總結(github 中的代碼包括這些更改):

  • 從下載 ZoomingPDFViewerhttp://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html 并在 XCode 中打開
  • 更改了構建設置 |架構 |Base SDK 到最新的 iOS (iOS 4.3) 更改了構建設置 |GCC 4.2 - 語言 |根據 Objective-C++ 編譯源代碼
  • 從項目中刪除了 TestPage.pdf
  • 在項目中添加了whoiam 5 24 cropped 3-2.pdf"
  • PDFScrollView *scrollView; 添加到 ZoomingPDFViewerViewController
  • ZoomingPDFViewerViewController 中的 loadView 更改為初始化 scrollView 而不是 sv
  • 在 PDFScrollview.m 中將 viewDidLoadhandleTapFrom:recognizerzoomOut 添加到 ZoomingPDFViewerViewController
  • 注釋掉 scrollViewDidEndZooming:withView:atScalescrollViewWillBeginZooming:withView: 因為它們在圖像背景中做的事情會分散手頭的問題

非常感謝您對我的包容,以及任何和所有的幫助!

解決方案

關于縮放的最棘手的事情之一是它總是發生在一個稱為錨點的點周圍.我認為理解它的最好方法是想象一個坐標系疊加在另一個坐標系之上.假設 A 是您的外部坐標系,B 是內部坐標系(B 將是滾動視圖).當B的偏移量為(0,0),比例為1.0時,則點B(0,0)對應A(0,0),一般情況下B(x,y) = A(x,y).

進一步,如果 B 的偏移量是 (xOff, yOff) 則 B(x,y) = A(x - xOff, y - yOff).同樣,這仍然假設縮放比例為 1.0.

現在,讓偏移量再次為 (0,0) 并想象當您嘗試縮放時會發生什么.屏幕上一定有一個點在縮放時不會移動,并且每隔一個點都會從該點向外移動.這就是錨點定義的內容.如果您的錨點是 (0,0),那么左下角的點將保持固定,而所有其他點都會向上和向右移動.在這種情況下,偏移量保持不變.

如果你的錨點是 (0.5, 0.5)(錨點是標準化的,即 0 到 1,所以 0.5 是一半),那么中心點保持固定,而所有其他點都向外移動.這意味著偏移量必須改變以反映這一點.如果它在 iPhone 上的縱向模式下縮放到 2.0,則錨點 x 值將移動屏幕寬度的一半,即 320/2 = 160.

滾動視圖內容視圖在屏幕上的實際位置由偏移量和錨點定義.因此,如果您只是簡單地更改下面的圖層錨點而不對偏移量進行相應更改,您將看到視圖似乎跳轉到不同的位置,即使偏移量相同.

我猜這是這里的根本問題.當您為縮放設置動畫時,Core Animation 必須選擇一個新的錨點,以便縮放看起來"正確.這也將更改偏移量,以使屏幕上的視圖實際可見區域不會跳轉.嘗試在整個過程中的不同時間記錄錨點的位置(它在您使用 Views層"屬性訪問的任何 View 的底層 CALayer 上定義).

另外,請參閱文檔 這里 對于漂亮的圖片,可能比我在這里給出的情況描述要好得多:)

最后,這是我在應用程序中使用的一段代碼,用于更改圖層的錨點而不使其在屏幕上移動.

-(CGPoint)setNewAnchorPointWithoutMoving:(CGPoint)newAnchor {CGPoint currentAnchor = CGPointMake(self.anchorPoint.x * self.contentSize.width,self.anchorPoint.y * self.contentSize.height);CGPoint offset = CGPointMake((1 - self.scale) * (currentAnchor.x - newAnchor.x),(1 - self.scale) * (currentAnchor.y - newAnchor.y));self.anchorPoint = CGPointMake(newAnchor.x/self.contentSize.width,newAnchor.y/self.contentSize.height);self.position = CGPointMake(self.position.x + offset.x, self.position.y + offset.y);返回偏移量;}

Executive Summary: At times UIScrollView makes an unwanted change to the value of contentOffset, thus causing the app to display the wrong location in the document being viewed. The unwanted change happens in conjunction to an animated change to the scroll view's zoomScale.

The Details: I'm having trouble when zooming out with CATiledLayer in a UIScrollView. The CATiledLayer holds a pdf, and when contentOffset is within a certain range, when I zoom out, the contentOffset is changed (that's the bug) before the zooming occurs. The contentOffset seems to be changed in Apple's code.

To illustrate the problem, I modified Apple's sample app, ZoomingPDFViewer. The code is on github: https://github.com/DirkMaas/ZoomingPDFViewer-bug

A tap will cause zoomScale to be changed to 0.5, using animateWithDuration, thus zooming out. If the UIScrollView's contentOffset.y is less than about 2700 or greater than 5900, the zoomScale animation works fine. If the tap happens when contentOffset.y is between those two values, the contentOffset.y will jump (not animated) to about 2700, and then the zoomScale animation will occur, but scrolling will occur at the same time, so that when the animation is done, the contentOffset.y is where it should be. But where does the jump come from?

For example, say the contentOffset.y is 2000 when the screen is tapped: the zoomScale animation works just fine; contentOffset.y is not changed.

But if the contentOffset.y is 4000 when the screen is tapped: the contentOffset.y will jump, without animation, to about 2700, and then zooming and scrolling will begin from that point and occur at the same time. When the animation is done, it looks as if we zoomed straight back from 4000, so we end up in the right place, but the behavior is wrong.

A note on the UI:

  • the text can be scrolled vertically in the normal way
  • the text can be zoomed in and out by pinching in the normal way
  • a single tap will cause the zoomScale to be set to 0.5; the change is animated

I've noticed that if zoomScale is greater than 0.5, the jump is not so big. Also, if I use setZoomScale:animated: instead of animateWithDuration, the bug disappears, but I can't use it because I need to chain animations.

Here is a summary of what I did (the code in github includes these changes):

  • Downloaded ZoomingPDFViewer from http://developer.apple.com/library/ios/#samplecode/ZoomingPDFViewer/Introduction/Intro.html and opened it in XCode
  • Changed Build Settings | Architectures | Base SDK to Latest iOS (iOS 4.3) changed Build Settings | GCC 4.2 - Language | Compile Sources As to Objective-C++
  • removed TestPage.pdf from the project
  • added "whoiam 5 24 cropped 3-2.pdf" to the project in its place
  • added PDFScrollView *scrollView; to ZoomingPDFViewerViewController class
  • changed loadView in ZoomingPDFViewerViewController to initialize scrollView instead of sv
  • added viewDidLoad, handleTapFrom:recognizer and zoomOut to ZoomingPDFViewerViewController in PDFScrollview.m
  • commented out scrollViewDidEndZooming:withView:atScale and scrollViewWillBeginZooming:withView: because they do stuff in the image background that distracts from the issue at hand

Thanks so much for bearing with me, and any and all help!

解決方案

One of the trickiest things to understand about zooming is that it always happens around a point called the Anchor Point. I think the best way to understand it is to imagine one coordinate system layered on top of another. Say A is your outer coordinate system, B is the inner (B will be the scrollview). When the offset of B is (0,0) and the scale is 1.0, then the point B(0,0) corresponds to A(0,0), and in general B(x,y) = A(x,y).

Further, if the offset of B is (xOff, yOff) then B(x,y) = A(x - xOff, y - yOff). Again, this is still assuming zoom scale is 1.0.

Now, let the offset be (0,0) again and imagine what happens when you try to zoom. There must be a point on the screen that doesn't move when you zoom, and every other point moves outward from that point. That is what the anchor point defines. If your anchor is (0,0) then the bottom left point will remain fixed while all other points move up and to the right. In this case the offset remains the same.

If your anchor point is (0.5, 0.5) (the anchor point is normalized, i.e. 0 to 1, so 0.5 is half way across), then the center point stays fixed while all other points move outward. This means the offset has to change to reflect that. If it's on an iPhone in portrait mode and you zoom to scale 2.0, the anchor point x value will move half the screen width, 320/2 = 160.

The actual position of the scroll views content view on screen is defined by BOTH the offset and the anchor point. So, if you simply change the layers anchor point underneath without making a corresponding change to the offset, you will see the view appear to jump to a different location, even though the offset is the same.

I am guessing that this is the underlying problem here. When you are animating the zoom, Core Animation must be picking a new anchor point so the zooming "looks" right. This will also change the offset so that the views actual visible region on screen doesn't jump. Try logging the location of the anchor point at various times throughout this process (it is defined on the underlying CALayer of any View which you access with a Views "layer" property).

Also, please see the documentation here for pretty pictures and likely a far better description of the situation than I've given here :)

Finally, here is a snippet of code I used in an app to change the anchor point of a layer without it moving on screen.

-(CGPoint)setNewAnchorPointWithoutMoving:(CGPoint)newAnchor {
    CGPoint currentAnchor = CGPointMake(self.anchorPoint.x * self.contentSize.width,
                                        self.anchorPoint.y * self.contentSize.height);

    CGPoint offset = CGPointMake((1 - self.scale) * (currentAnchor.x - newAnchor.x),
                                 (1 - self.scale) * (currentAnchor.y - newAnchor.y));


    self.anchorPoint = CGPointMake(newAnchor.x / self.contentSize.width,
                                   newAnchor.y / self.contentSize.height);

    self.position = CGPointMake(self.position.x + offset.x, self.position.y + offset.y);

    return offset;
}

這篇關于在 UIScrollView 中為 zoomScale 設置動畫時不需要的滾動的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

how to set scrollview content size in swift 3.0(如何在 swift 3.0 中設置滾動視圖內容大小)
Stop a UITableView from automatically scrolling(阻止 UITableView 自動滾動)
iOS UIScrollView Lazy Loading(iOS UIScrollView 延遲加載)
using iOS 6.0 SDK and building for iOS 5 Target causes UIScrollView setMinimumZoomScale to fail when running on iOS 5 simulator(在 iOS 5 模擬器上運行時,使用 iOS 6.0 SDK 并為 iOS 5 Target 構建會導致 UIScrollView setMinimumZ
Create partial-screen UIPageViewController programmatically(以編程方式創建部分屏幕 UIPageViewController)
how to make an ImageView zoomable with or without ScrollView.?(如何使用或不使用 ScrollView 使 ImageView 可縮放?)
主站蜘蛛池模板: www午夜视频 | 在线免费小视频 | 久久一 | 日本在线视频一区二区 | 欧美一区成人 | 黄色在线免费播放 | 高清一区二区三区 | 91看片官网 | 在线免费观看黄a | 一区二区三区福利视频 | 久久久久久久久久久久久久国产 | 国产精品久久久久久久久久久久 | 国产一区二区免费 | 精品国产99| 中文字幕一区在线观看视频 | 黄网站在线观看 | 天天干视频网 | av天天操 | 99精品国产一区二区青青牛奶 | 一二三区在线 | 黄在线 | 91国在线观看 | 欧美激情久久久 | 欧美一区二区三区大片 | 亚洲精品九九 | 亚洲一区二区三区视频免费观看 | 伊人亚洲 | 欧美日韩在线高清 | 亚洲女人的天堂 | av网站免费| 亚洲欧美v | 一区在线视频 | 久久国产一区 | 视频一区二区三区在线观看 | 日韩在线免费视频 | 精品国产一区二区三区久久久久久 | av一区二区三区 | 欧美激情一区二区三区 | 国产精品av久久久久久久久久 | 国产在线精品一区二区三区 | 欧美日在线 |