diff --git a/docs/release-notes-player.txt b/docs/release-notes-player.txt
index 28f2381bec79b1f46f032334b2255bb8d316b401..7df24784e9004cebbf3e80eb9798142a787719d6 100644
--- a/docs/release-notes-player.txt
+++ b/docs/release-notes-player.txt
@@ -3,6 +3,7 @@ Player
 1.20.0
 - Fix dimensions of images with dynamicPositioning and fixedSize
 - Fix display of fixed size dynamic elements on iPad
+- Fix selecting and marking of text on iPad
 
 1.19.0
 - Remove border of slider rectangle in number line mode at position 0
diff --git a/projects/common/components/marking-bar/marking-button.component.ts b/projects/common/components/marking-bar/marking-button.component.ts
index d09610b30d009fd31e9d7c87893d4e22c6e29652..208978aaa00d1a492ea56c0d91cc2a88026d7154 100644
--- a/projects/common/components/marking-bar/marking-button.component.ts
+++ b/projects/common/components/marking-bar/marking-button.component.ts
@@ -10,8 +10,8 @@ import {
             [style.border-color]="selected ? 'black' : color"
             mat-mini-fab
             [style.background-color]="color"
-            (mousedown)="$event.stopPropagation();"
-            (click)="selected = !selected; selectedChanged.emit({ selected, mode, color })">
+            (mousedown)="emitSelectedChanged($event)"
+            (touchstart)="emitSelectedChanged($event)">
       <mat-icon *ngIf="mode === 'mark'"
                 class="marking-icon">border_color
       </mat-icon>
@@ -35,4 +35,13 @@ export class MarkingButtonComponent {
     mode: 'mark' | 'delete',
     color: string,
   }>();
+
+  emitSelectedChanged(event: TouchEvent | MouseEvent): void {
+    if (event instanceof TouchEvent && event.cancelable) {
+      event.preventDefault();
+    }
+    event.stopPropagation();
+    this.selected = !this.selected;
+    this.selectedChanged.emit({ selected: this.selected, mode: this.mode, color: this.color });
+  }
 }
diff --git a/projects/common/ui-elements/text/text.component.ts b/projects/common/ui-elements/text/text.component.ts
index 7b0c52612531f4111def440d3046d7327a329d7b..8af9f767e99cff6ca1ffe73c2888ba8a5db07203 100644
--- a/projects/common/ui-elements/text/text.component.ts
+++ b/projects/common/ui-elements/text/text.component.ts
@@ -14,11 +14,11 @@ import { ValueChangeElement } from '../../models/uI-element';
            [style.width]="elementModel.positionProps.fixedSize ? elementModel.width + 'px' : '100%'"
            [style.height]="elementModel.positionProps.fixedSize ? elementModel.height + 'px' : 'auto'">
         <aspect-marking-bar
-          *ngIf="elementModel.highlightableYellow ||
+            *ngIf="elementModel.highlightableYellow ||
               elementModel.highlightableTurquoise ||
               elementModel.highlightableOrange"
-          [elementModel]="elementModel"
-          (selectionChanged)="onSelectionChanged($event)">
+            [elementModel]="elementModel"
+            (selectionChanged)="onSelectionChanged($event)">
         </aspect-marking-bar>
         <div #textContainerRef class="text-container"
              [class.orange-selection]="selectedColor === 'orange'"
@@ -34,9 +34,8 @@ import { ValueChangeElement } from '../../models/uI-element';
              [style.font-style]="elementModel.fontProps.italic ? 'italic' : ''"
              [style.text-decoration]="elementModel.fontProps.underline ? 'underline' : ''"
              [innerHTML]="elementModel.text | safeResourceHTML"
-             (mousedown)="elementModel.highlightableYellow ||
-               elementModel.highlightableTurquoise ||
-               elementModel.highlightableOrange ? startSelection.emit($event) : null">
+             (touchstart)="emitStartSelection($event)"
+             (mousedown)="emitStartSelection($event)">
         </div>
       </div>
     </div>
@@ -59,7 +58,7 @@ import { ValueChangeElement } from '../../models/uI-element';
 export class TextComponent extends ElementComponent {
   @Input() elementModel!: TextElement;
   @Output() elementValueChanged = new EventEmitter<ValueChangeElement>();
-  @Output() startSelection = new EventEmitter<MouseEvent>();
+  @Output() startSelection = new EventEmitter<MouseEvent | TouchEvent>();
   @Output() applySelection = new EventEmitter<{
     active: boolean,
     mode: 'mark' | 'delete',
@@ -71,6 +70,14 @@ export class TextComponent extends ElementComponent {
 
   @ViewChild('textContainerRef') textContainerRef!: ElementRef;
 
+  emitStartSelection(event: TouchEvent | MouseEvent): void {
+    if (this.elementModel.highlightableYellow ||
+      this.elementModel.highlightableTurquoise ||
+      this.elementModel.highlightableOrange) {
+      this.startSelection.emit(event);
+    }
+  }
+
   onSelectionChanged(selection: {
     active: boolean,
     mode: 'mark' | 'delete',
diff --git a/projects/player/src/app/components/element-container/element-container.component.ts b/projects/player/src/app/components/element-container/element-container.component.ts
index 995ecb212946b949d36bc2efa1c4d154f4613718..3977a571ed489be0bec67697f21f1b77eefc5f52 100644
--- a/projects/player/src/app/components/element-container/element-container.component.ts
+++ b/projects/player/src/app/components/element-container/element-container.component.ts
@@ -194,35 +194,58 @@ export class ElementContainerComponent implements OnInit {
     if (elementComponent.startSelection) {
       elementComponent.startSelection
         .pipe(takeUntil(this.ngUnsubscribe))
-        .subscribe((mouseDown: MouseEvent) => {
+        .subscribe((pointerDown: MouseEvent | TouchEvent) => {
           this.isMarkingBarOpen = false;
-          this.nativeEventService.mouseUp
+
+          this.nativeEventService.pointerUp
             .pipe(takeUntil(this.ngUnsubscribe), first())
-            .subscribe((mouseUp: MouseEvent) => this.stopSelection(mouseUp, mouseDown, elementComponent));
+            .subscribe((pointerUp: TouchEvent | MouseEvent) => {
+              if (pointerUp.cancelable) {
+                pointerUp.preventDefault();
+              }
+              this.stopSelection(
+                this.getClientPointFromEvent(pointerUp),
+                pointerUp.ctrlKey,
+                this.getClientPointFromEvent(pointerDown),
+                elementComponent
+              );
+            });
         });
     }
   }
 
-  private stopSelection(mouseUp: MouseEvent, mouseDown: MouseEvent, elementComponent: TextComponent) {
+  private stopSelection(
+    mouseUp: { clientX: number, clientY: number },
+    ctrlKey: boolean,
+    downPosition: { clientX: number, clientY: number },
+    elementComponent: TextComponent
+  ) {
     const selection = window.getSelection();
     if (selection && TextMarker.isSelectionValid(selection) && selection.rangeCount > 0) {
-      if (!TextMarker.isRangeInside(selection.getRangeAt(0),
-        elementComponent.textContainerRef.nativeElement) ||
-        (mouseUp.ctrlKey)) {
+      if (!TextMarker.isRangeInside(selection.getRangeAt(0), elementComponent.textContainerRef.nativeElement) ||
+        (ctrlKey)) {
         selection.removeAllRanges();
       } else if (this.selectedMode && this.selectedColor) {
         this.applySelectionToText(this.selectedMode, this.selectedColor);
       } else if (!this.isMarkingBarOpen) {
-        this.openMarkingBar(mouseUp, mouseDown);
+        this.openMarkingBar(mouseUp, downPosition);
       }
     }
   }
 
-  private openMarkingBar(mouseUp: MouseEvent, mouseDown: MouseEvent) {
-    this.markingBarPosition.left = mouseDown.clientY > mouseUp.clientY ? mouseDown.clientX : mouseUp.clientX;
-    this.markingBarPosition.top = mouseDown.clientY > mouseUp.clientY ? mouseDown.clientY : mouseUp.clientY;
+  private getClientPointFromEvent = (event: MouseEvent | TouchEvent): { clientX: number, clientY: number } => ({
+    clientX: (event instanceof MouseEvent) ? event.clientX : event.changedTouches[0].clientX,
+    clientY: (event instanceof MouseEvent) ? event.clientY : event.changedTouches[0].clientY
+  });
+
+  private openMarkingBar(
+    mouseUp: { clientX: number, clientY: number },
+    downPosition: { clientX: number, clientY: number }
+  ) {
+    this.markingBarPosition.left = downPosition.clientY > mouseUp.clientY ? downPosition.clientX : mouseUp.clientX;
+    this.markingBarPosition.top = downPosition.clientY > mouseUp.clientY ? downPosition.clientY : mouseUp.clientY;
     this.isMarkingBarOpen = true;
-    this.nativeEventService.mouseDown
+    this.nativeEventService.pointerDown
       .pipe(takeUntil(this.ngUnsubscribe), first())
       .subscribe(() => this.closeMarkingBar());
   }
@@ -235,12 +258,13 @@ export class ElementContainerComponent implements OnInit {
     if (elementComponent.applySelection) {
       elementComponent.applySelection
         .pipe(takeUntil(this.ngUnsubscribe))
-        .subscribe((selection:
-        {
-          active: boolean,
-          mode: 'mark' | 'delete',
-          color: string;
-        }) => {
+        .subscribe((
+          selection: {
+            active: boolean,
+            mode: 'mark' | 'delete',
+            color: string;
+          }
+        ) => {
           if (selection.active) {
             this.selectedColor = selection.color;
             this.selectedMode = selection.mode;
diff --git a/projects/player/src/app/services/native-event.service.ts b/projects/player/src/app/services/native-event.service.ts
index a7b019f8e87a5dde7f55c0257b7745764042bb7a..07bd9cb8a605fe0f4aa888182c24354ed6cd6dac 100644
--- a/projects/player/src/app/services/native-event.service.ts
+++ b/projects/player/src/app/services/native-event.service.ts
@@ -10,8 +10,8 @@ import { mergeMap } from 'rxjs/operators';
 })
 export class NativeEventService {
   private _focus = new Subject<boolean>();
-  private _mouseUp = new Subject<MouseEvent>();
-  private _mouseDown = new Subject<MouseEvent>();
+  private _pointerUp = new Subject<MouseEvent | TouchEvent>();
+  private _pointerDown = new Subject<MouseEvent | TouchEvent>();
   private _resize = new Subject<number>();
 
   constructor(@Inject(DOCUMENT) private document: Document) {
@@ -23,15 +23,33 @@ export class NativeEventService {
         () => this._focus.next(document.hasFocus())// Do something with the event here
       );
 
-    fromEvent(window, 'mouseup')
-      .subscribe((mouseEvent: Event) => {
-        this._mouseUp.next(mouseEvent as MouseEvent);
-      });
+    from(['mouseup', 'touchend'])
+      .pipe(
+        mergeMap(event => fromEvent(window, event))
+      )
+      .subscribe(
+        (event: Event) => {
+          if (event instanceof TouchEvent) {
+            this._pointerUp.next(event as TouchEvent);
+          } else {
+            this._pointerUp.next(event as MouseEvent);
+          }
+        }
+      );
 
-    fromEvent(window, 'mousedown')
-      .subscribe((mouseEvent: Event) => {
-        this._mouseDown.next(mouseEvent as MouseEvent);
-      });
+    from(['mousedown', 'touchstart'])
+      .pipe(
+        mergeMap(event => fromEvent(window, event))
+      )
+      .subscribe(
+        (event: Event) => {
+          if (event instanceof TouchEvent) {
+            this._pointerDown.next(event as TouchEvent);
+          } else {
+            this._pointerDown.next(event as MouseEvent);
+          }
+        }
+      );
 
     fromEvent(window, 'resize')
       .subscribe(() => this._resize.next(window.innerWidth));
@@ -41,12 +59,12 @@ export class NativeEventService {
     return this._focus.asObservable();
   }
 
-  get mouseUp(): Observable<MouseEvent> {
-    return this._mouseUp.asObservable();
+  get pointerUp(): Observable<MouseEvent | TouchEvent> {
+    return this._pointerUp.asObservable();
   }
 
-  get mouseDown(): Observable<MouseEvent> {
-    return this._mouseDown.asObservable();
+  get pointerDown(): Observable<MouseEvent | TouchEvent> {
+    return this._pointerDown.asObservable();
   }
 
   get resize(): Observable<number> {