xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

Shell app on iOS 9 - [UITabBar unselectedItemTintColor]: unrecognized selector sent to instance #6739

Closed ianvink closed 5 years ago

ianvink commented 5 years ago

When I create a hello-world with-tabs Shell app, then run on a iOS 9.3 device, it crashes with:

[UITabBar unselectedItemTintColor]: unrecognized selector sent to instance Xamarin.iOS: Received unhandled ObjectiveC exception: NSInvalidArgumentException -[UITabBar unselectedItemTintColor]: unrecognized selector sent to instance 0x18082710

Steps to Reproduce

  1. Hello World with Tabs
  2. Run on iOS 9.3 device

Expected Behavior

Shell should check to ensure iOS can respond to that selector like this in old-fashioned Obj-C:

if ([[UITabBar appearance] respondsToSelector:@selector(setUnselectedItemTintColor:)]) { [[UITabBar appearance] setUnselectedItemTintColor:[UIColor blackColor]]; }

Actual Behavior

Crashes

Basic Information

Screen Shot 2019-07-01 at 7 29 58 PM

ianvink commented 5 years ago

Repo here, run against iOS 9.3 - App3.zip

samhouts commented 5 years ago

@ianvink I tried this on an iOS 9.3 simulator, and it didn't crash. Can you confirm if it crashes on sim for you, or just device? Thanks!

ianvink commented 5 years ago

It crashes the same on sim and devices. I run VS 2019 on Windows 10 with VS Mac on a MacBookPro . Both up to date

image

PureWeen commented 5 years ago

@ianvink if you run your sample on an iPad 2 or an iPhone 4s to you see the crash?

PureWeen commented 5 years ago

Also @ianvink are you running Mojave or High Sierra?

ianvink commented 5 years ago

iPad Air 3 running. iOS 9.3

Mac OS, what ever is latest production release

PureWeen commented 5 years ago

@ianvink can you test on the iPad 2 or an iPhone 4s simulator and let me know if you see the same crash?

PureWeen commented 5 years ago

@ianvink can you give me the output on your vsmac from

Visual Studio => About Visual Studio => Show Details => Copy Information

ianvink commented 5 years ago

=== Visual Studio Enterprise 2019 for Mac ===

Version 8.1.5 (build 9) Installation UUID: c055baa8-d5b5-4372-91f9-64a91569bae5 GTK+ 2.24.23 (Raleigh theme) Xamarin.Mac 5.6.0.25 (d16-0 / 50f75273)

Package version: 518010028

=== Mono Framework MDK ===

Runtime: Mono 5.18.1.28 (2018-08/223ea7ef92e) (64-bit) Package version: 518010028

=== NuGet ===

Version: 5.0.2.5988

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet Runtime Versions: 2.1.11 2.1.9 2.1.8 2.1.2 2.1.1 SDK: /usr/local/share/dotnet/sdk/2.1.700/Sdks SDK Versions: 2.1.700 2.1.505 2.1.504 2.1.302 2.1.301 MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.18.1/lib/mono/msbuild/Current/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.6.10 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Updater ===

Version: 11

=== Apple Developer Tools ===

Xcode 10.2.1 (14490.122) Build 10E1001

=== Xamarin.Mac ===

Xamarin.Mac not installed. Can't find /Library/Frameworks/Xamarin.Mac.framework/Versions/Current/Version.

=== Xamarin.iOS ===

Version: 12.10.0.157 (Visual Studio Enterprise) Hash: 6bd94753 Branch: d16-1 Build date: 2019-06-12 17:28:47-0400

=== Xamarin Designer ===

Version: 16.1.0.467 Hash: f1657e133 Branch: remotes/origin/d16-1-new-document-model Build date: 2019-06-18 21:57:42 UTC

=== Xamarin.Android ===

Version: 9.3.0.23 (Visual Studio Enterprise) Commit: HEAD/d0b48056f Android SDK: /Users/vink/Library/Developer/Xamarin/android-sdk-macosx Supported Android versions: 8.1 (API level 27)

SDK Tools Version: 26.1.1 SDK Platform Tools Version: 29.0.1 SDK Build Tools Version: 27.0.3

Build Information: Mono: mono/mono/2018-08@3a07bd426d3 Java.Interop: xamarin/java.interop/d16-1@5ddc3e3 LibZipSharp: grendello/LibZipSharp/d16-1@44de300 LibZip: nih-at/libzip/rel-1-5-1@b95cf3f ProGuard: xamarin/proguard/master@905836d SQLite: xamarin/sqlite/3.27.1@8212a2d Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-1@acabd26

=== Microsoft Mobile OpenJDK ===

Java SDK: /Users/vink/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_8.0.25 1.8.0-25 Android Designer EPL code available here: https://github.com/xamarin/AndroidDesigner.EPL

=== Android Device Manager ===

Version: 1.2.0.44 Hash: aac645b Branch: remotes/origin/d16-1 Build date: 2019-05-29 19:55:24 UTC

=== Xamarin Inspector ===

Version: 1.4.3 Hash: db27525 Branch: 1.4-release Build date: Mon, 09 Jul 2018 21:20:18 GMT Client compatibility: 1

=== Build Information ===

Release ID: 801050009 Git revision: bd0ab28ba941b19b39322247db020dcd0fb305d0 Build date: 2019-07-03 17:15:21+00 Build branch: release-8.1 Xamarin extensions: 8cc25b5cb090e6c23b62a7901000c299977eb08d

=== Operating System ===

Mac OS X 10.14.5 Darwin 18.6.0 Darwin Kernel Version 18.6.0 Thu Apr 25 23:16:27 PDT 2019 root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64

=== Enabled user installed extensions ===

NuGet Package Management Extensions 0.18

ianvink commented 5 years ago

after the most recent update to VSMac, I can no longer see iPhone 4 simulators. You can see I have them installed in XCode.

I get the same error from a iOS 9.3 iPad device. (the only non 64 bit device I have)

Screen Shot 2019-07-18 at 8 14 29 PM

PureWeen commented 5 years ago

@ianvink we searched the catacombs and found a device that we can replicate this on!

bytefish commented 5 years ago

Is there any workaround for this issue? I have the same issue. Here is my error log:

2019-08-05 09:04:15.875 ...Mobile.iOS[7802:1365980] Splitview controller <Xamarin_Forms_Platform_iOS_TabletShellFlyoutRenderer: 0x16ba9e00> is expected to have a view controller at index 0 before it's used!
2019-08-05 09:04:16.226 ...Mobile.iOS[7802:1365980] -[UITabBar unselectedItemTintColor]: unrecognized selector sent to instance 0x171d0270
2019-08-05 09:04:16.240 ...Mobile.iOS[7802:1365980] critical: Stacktrace:
2019-08-05 09:04:16.240 ...Mobile.iOS[7802:1365980] critical:   at <unknown> <0xffffffff>
2019-08-05 09:04:16.241 ...Mobile.iOS[7802:1365980] critical:   at (wrapper managed-to-native) ObjCRuntime.Messaging.IntPtr_objc_msgSend (intptr,intptr) <0x00043>
2019-08-05 09:04:16.242 ...Mobile.iOS[7802:1365980] critical:   at UIKit.UITabBar.get_UnselectedItemTintColor () [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.4.0.64/src/Xamarin.iOS/UIKit/UITabBar.g.cs:597
2019-08-05 09:04:16.245 ...Mobile.iOS[7802:1365980] critical:   at Xamarin.Forms.Platform.iOS.SafeShellTabBarAppearanceTracker.SetAppearance (UIKit.UITabBarController,Xamarin.Forms.ShellAppearance) [0x0004a] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\SafeShellTabBarAppearanceTracker.cs:37
2019-08-05 09:04:16.246 ...Mobile.iOS[7802:1365980] critical:   at Xamarin.Forms.Platform.iOS.ShellItemRenderer.UpdateShellAppearance (Xamarin.Forms.ShellAppearance) [0x00016] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellItemRenderer.cs:215
2019-08-05 09:04:16.246 ...Mobile.iOS[7802:1365980] critical:   at <unknown> <0xffffffff>
2019-08-05 09:04:16.247 ...Mobile.iOS[7802:1365980] critical: 
pauldipietro commented 5 years ago

@ianvink @bytefish I'd like to talk to people who still deploy to iOS 9 in order to learn about their use cases, so if you don't mind getting in touch, I'd appreciate talking about it. My email is paul.dipietro@microsoft.com.

MikGru commented 5 years ago

@pauldipietro I have the same error as @bytefish . I'm deploying to an iPad Mini with OS 9.3.5. For use case: our app is simple, uses little resources and because our clients are resistant to purchasing newer devices, my employer would like to continue to support older devices as long as we can. Any workaround or fix would be greatly appreciated.

ianvink commented 5 years ago

@pauldipietro The problem is that iPads don't get replaced very often so older OSs are around for longer.

jfversluis commented 5 years ago

Seeing the error message it shows similarities with #6862

MikGru commented 5 years ago

@pauldipietro @samhouts Is this going to get fixed? If so, do you have an approximate timeline. This is the one issue preventing me from releasing the new version of my app, and asking our users to upgrade their iPads is not an option for me. I need to know whether I need to replace Shell with something else...

MikGru commented 5 years ago

For anyone with this issue, I found a workaround. Put the following in your iOS custom renderers folder:

using YourNamespace.iOS.CustomRenderers;
using System;
using System.ComponentModel;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(Shell), typeof(MyShellRenderer))]
namespace YourNamespace.iOS.CustomRenderers {

  public class MyShellRenderer : ShellRenderer {
    protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker() {
      return new MySafeShellTabBarAppearanceTracker();
    }
  }

  public class MySafeShellTabBarAppearanceTracker : IShellTabBarAppearanceTracker {
    UIColor _defaultBarTint;
    UIColor _defaultTint;
    UIColor _defaultUnselectedTint;

    public void ResetAppearance(UITabBarController controller) {
      if (_defaultTint == null)
        return;

      var tabBar = controller.TabBar;
      tabBar.BarTintColor = _defaultBarTint;
      tabBar.TintColor = _defaultTint;
      tabBar.UnselectedItemTintColor = _defaultUnselectedTint;
    }

    public void SetAppearance(UITabBarController controller, ShellAppearance appearance) {
      IShellAppearanceElement appearanceElement = appearance;
      var backgroundColor = appearanceElement.EffectiveTabBarBackgroundColor;
      var foregroundColor = appearanceElement.EffectiveTabBarForegroundColor; // currently unused
      var disabledColor = appearanceElement.EffectiveTabBarDisabledColor; // unused on iOS
      var unselectedColor = appearanceElement.EffectiveTabBarUnselectedColor;
      var titleColor = appearanceElement.EffectiveTabBarTitleColor;

      var tabBar = controller.TabBar;
      bool operatingSystemHasUnselectedTint = UIDevice.CurrentDevice.CheckSystemVersion(10, 0);
      if (_defaultTint == null) {
        _defaultBarTint = tabBar.BarTintColor;
        _defaultTint = tabBar.TintColor;
        if (operatingSystemHasUnselectedTint) {
          _defaultUnselectedTint = tabBar.UnselectedItemTintColor;
        }
      }

      if (!backgroundColor.IsDefault)
        tabBar.BarTintColor = backgroundColor.ToUIColor();
      if (!titleColor.IsDefault)
        tabBar.TintColor = titleColor.ToUIColor();
      if (operatingSystemHasUnselectedTint) {
        if (!unselectedColor.IsDefault)
          tabBar.UnselectedItemTintColor = unselectedColor.ToUIColor();
      }
    }

    public void UpdateLayout(UITabBarController controller) {
    }

    #region IDisposable Support
    protected virtual void Dispose(bool disposing) {
    }

    public void Dispose() {
      Dispose(true);
    }
    #endregion

  }
}
samhouts commented 5 years ago

@JRPMike This is on the backlog, but I do not have an estimate of when we may begin work on it. I'm glad to see that you have found a workaround! Thanks!

ianvink commented 5 years ago

I can confirm that @JRPMike solution worked well for us too on a large project. iOS 9 works well with Shell. I'll do a blog post on how use @JRPMike 's workaround to make it work for others.

ianvink commented 5 years ago

Blog post published with full credits to this forum and the author of the fix. https://ianvink.wordpress.com/2019/08/14/xamarin-forms-shell-how-to-make-it-work-on-ios-9/