Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   iOS UIScrollView in UIPageViewController (https://www.delphipraxis.net/178838-uiscrollview-uipageviewcontroller.html)

Crocotronic 30. Jan 2014 19:53

UIScrollView in UIPageViewController
 
Guten Abend,
ich brauche dringend Eure Hilfe bei folgendem Problem:
  • Ein UIPageViewController besteht aus 5 Seiten
  • Jede Seite besitzt ein UIScrollView (mit oder ohne Unterobjekte spielt keine Rolle)
  • Das UIScrollView hat die Eigenschafften Align=alClient und MarginTop=45
Nun passiert es bei allen 2-3 App-Aufrufen, dass zufällig ausgewählte Seiten sich nicht mit der Wisch-Geste umblättern lassen.
Aber:
Wischt man ganz unten oder ganz Oben am Rand des UIPageViewControllers, so funktioniert das Umblättern auch bei den "infizierten" Seiten einwandfrei.
Auch ein Klick auf den linken oder rechten Seiterand funktioniert.
Nur in der Mitte vom ScrollView werden keine Gesten erkannt.

Was Jens vermutet hat, kann ich aufgrund der gerade genannten Umstände ausschließen:
Zitat:

Blättert nicht zu einer vermeidlich vorhandenen Seite, GestureRecogniter nicht verbunden, NullPointerException ... Das hört sich genau nach solchen Speicherbereinigungseffekten an.
Ich zeig euch einfach mal mein Code (stark vereinfacht, mag deshalb vielleicht an manchen Stellen sinnlos erscheinen). Den Fehler konnte ich leider nicht in einem Testprojekt reproduzieren.
Delphi-Quellcode:
unit TestVieweriOS;

interface

uses
  SysUtils, DateUtils, Classes, System.Types, System.UITypes, Generics.Collections,
  iOSapi.UIKit, iOSapi.Foundation, iOSapi.CocoaTypes, iOSapi.CoreGraphics,
  MacApi.ObjectiveC, MacApi.ObjcRuntime,
  FMX.Types, FMX.TMSNativeUIScrollView, FMX.Dialogs, FMX.TMSNativeUIButton,
  FMX.TMSNativeUIViewController, FMX.TMSNativeUIPageViewController,
  FMX.TMSNativeUIBaseControl, FMX.TMSNativeUIView, FMX.TMSNativeUILabel,
  Interfaces.VPlanController.VPlanViewer;

type
  TViewerElement = class(TTMSFMXNativeUIViewController)
  private
   FContainer: TTMSFMXNativeUIScrollView;
   procedure Clear;
  public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
  end;

type
  TTestViewer = class(TTMSFMXNativeUIView)
  private
   FPager: TTMSFMXNativeUIPageViewController;
   FViewElements: array[0..4] of TViewerElement;
  public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
  end;

implementation

{ TTestViewer }

constructor TTestViewer.Create(AOwner: TComponent);
var n: Integer;
begin
 inherited;
 FPager:= TTMSFMXNativeUIPageViewController.Create(Self);
 FPager.Parent:= Self;
 FPager.Align:= TAlignLayout.alClient;

 for n:= Low(FViewElements) to High(FViewElements) do
 begin
  FViewElements[n]:= TViewerElement.Create(FPager);
  with FViewElements[n] do
  begin
   Parent:= FPager;
   Align:= TAlignLayout.alClient;
   Initialize;
  end;
  FPager.Pages.Add.View:= FViewElements[n];
 end;
 FPager.Initialize;
end;

destructor TTestViewer.Destroy;
var n: Integer;
begin
 for n:= Low(FViewElements) to High(FViewElements) do
  FViewElements[n].DisposeOf;
 FPager.DisposeOf;
 inherited;
end;

{ TViewerElement }

constructor TViewerElement.Create(AOwner: TComponent);
begin
 inherited;
 // ----------- PROBLEM ----------- //
 FContainer:= TTMSFMXNativeUIScrollView.Create(Self);
 with FContainer do
 begin
  Parent:= Self;
  Align:= TAlignLayout.alClient;
  ScrollView.setContentSize(CGSizeMake(FWidth,FHeight));
  Margins.Top:= CONTAINER_MARGIN_TOP;
  Initialize;
 end;
 // ------------------------------ //
end;

destructor TViewerElement.Destroy;
begin
 FContainer.DisposeOf;
 inherited;
end;

procedure TViewerElement.Clear;
begin
 FContainer.ScrollView.subviews.makeObjectsPerformSelector(sel_getUid('removeFromSuperview'));
end;

end.
Der PageViewController funktioniert einwandfrei, sobald ich das UIScrollView nicht erzeuge.
Hoffe, dass mir jemand helfen kann. Das Problem liegt mir schon ein Weilchen im Magen...

Viele Grüße
Croco

jensw_2000 30. Jan 2014 23:12

AW: UIScrollView in UIPageViewController
 
Ich habe nur 2 wage Ideen für Dich.
1.
Beißt sich eventuell die horizontale Swipe Gesture des UIScrollviews mit der horizontalen Swipe Gesture für das Umblättern des UIPageViewControllers?

Das halte ich allerdings für unwahrscheinlich, weil ich in meiner App fast das gleiche Szenario habe (UICollectionView auf UIPageView Seiten) und hier tritt dieser Effekt nicht auf. Die UICollectionView erbt ja von UIScrollView.

Testen könntest Du es recht einfach, indem du das horizontale Scrollen in deinem UIScrollview verbietest. Hier mal ein paar Ansätze.

2.
Schau mal in die Oxygene Methode, die ich dir in dem "UIPageViewController umblättern Thread" gepostet habe.
Ganz unten in meinem Code sind 3 Codezeilen, die in den Apple Beispielen stehen und die auch im Xcode "PageBased App Template" in dieser Methode vorhanden sind.

In deinem
Delphi-Quellcode:
TTestViewer.Create()
finde ich nur einen der Befehle wieder.

Delphi-Quellcode:
// Das hast Du sicher mit "FPager.Parent:=self;" richtig gelöst.
// Oder geht auch der originale API Befehl "self.addChildViewController(FPager);"?
addChildViewController(pageViewController);

// Nicht nur den PageViewController als ChildViewController hinzufügen, sondern
// auch den PageViewController.View als Subview in den RootView einbetten
view.addSubview(pageViewController.view);

// Das hier macht Apple auch immer...
// Dem RootView werden die GestureRecognizer des UIPageViewControllers zugewiesen.
view.gestureRecognizers := pageViewController.gestureRecognizers;
Hast Du das Starten bei einer bestimmten Seite hinbekommen?

Crocotronic 1. Feb 2014 17:27

AW: UIScrollView in UIPageViewController
 
Zitat:

Zitat von jensw_2000 (Beitrag 1246056)
Ich habe nur 2 wage Ideen für Dich.
1.
Beißt sich eventuell die horizontale Swipe Gesture des UIScrollviews mit der horizontalen Swipe Gesture für das Umblättern des UIPageViewControllers?

Das halte ich allerdings für unwahrscheinlich, weil ich in meiner App fast das gleiche Szenario habe (UICollectionView auf UIPageView Seiten) und hier tritt dieser Effekt nicht auf. Die UICollectionView erbt ja von UIScrollView.

Irgendwie sowas wird es sein.
Hab einfach mal ein bisschen rumgespielt und folgendes funktionert, aber eben ohne die GestureRecognizer vom ScrollView:
Delphi-Quellcode:
constructor TViewerElement.Create(AOwner: TComponent);
begin
 inherited;
 FContainer:= TTMSFMXNativeUIScrollView.Create(Self);
 with FContainer do
 begin
  Parent:= Self;
  Align:= TAlignLayout.alClient;
  ScrollView.setContentSize(CGSizeMake(FWidth,FHeight));
  Margins.Top:= CONTAINER_MARGIN_TOP;
  Initialize;
 end;
 FContainer.ScrollView.setGestureRecognizers(Self.View.gestureRecognizers);

 {...}
end;

Crocotronic 12. Mär 2014 20:44

AW: UIScrollView in UIPageViewController
 
Nach unzähligen Stunden hin- und her versuchen konnte ich den Fehler finden bzw. eingrenzen.

Dieses Objekt mit dem ScrollView und dem PageViewController befindet sich auf einem Pan-able View. Wenn ich das deaktiviere gibt es keine Probleme mehr.
Jetzt stellt sich aber die Frage, wie es dazu kommt, dass es dort ein Konflikt gibt und warum dieser nur zufällig eintritt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz