Unable to Stop a Coroutine in C#

I am making a timer that is supposed to stop when the player collects all of the cubes. I can collect all of the cubes just fine, the end text that displays when you collect everything works just the way I want it to, but the timer will not stop when I have collected all of the cubes. Here is the script:

using UnityEngine;
using System.Collections;

public class Collect : MonoBehaviour {

	public int CubesCollected;
	public int TotalCubes;
	private int Seconds;
	private int Minutes;
	public GUIText CubeCounter;
	public GUIText WinText;
	public GUIText Timer;

	void Start () {
		TotalCubes = 30;
		CubesCollected = 0;
		CubeCounter.text = ("Cubes Collected: 0 / " + TotalCubes.ToString ());
		WinText.text = ("");
		Timer.text = ("0:00");
		StartCoroutine("TimerFunction");
	}

	IEnumerator TimerFunction () {
			yield return new WaitForSeconds(1);
			Seconds++;
			if(Seconds == 60) {
				Seconds -= 60;
				Minutes++;
			}
			if(Seconds <= 10) {
				Timer.text = (Minutes.ToString() + ":0" + Seconds.ToString());
			}
			if(Seconds >= 10) {
				Timer.text = (Minutes.ToString() + ":" + Seconds.ToString());
			}
			StartCoroutine(TimerFunction());
	}
	void OnTriggerEnter (Collider other) {
		if(other.gameObject.tag == "Pickup") {
			other.gameObject.SetActive (false);
			CubesCollected++;
			CubeCounter.text = "Cubes Collected: " + CubesCollected.ToString () + " / " + TotalCubes.ToString ();
			if(CubesCollected == TotalCubes) {
				StopCoroutine("TimerFunction");
				WinText.text = ("Challenge Completed");
			}
		}
	}
}

I have tried yield break, that didn’t work. I can’t think of anything else that could be wrong. Bear with me, I am brand new to C#, and the structure itself of the script may be wrong entirely, despite everything else working.

You started your Coroutine every 1 second and have many Coroutine. System don’t now how Coroutine stopped you needed. I offer 2 solution you problem. First, create cycle while inside your coroutine:

 IEnumerator TimerFunction () {
  while(true) {
   yield return new WaitForSeconds(1);
   Seconds++;
   if(Seconds == 60) {
    Seconds -= 60;
    Minutes++;
   }
   if(Seconds <= 10) {
    Timer.text = (Minutes.ToString() + ":0" + Seconds.ToString());
   }
   if(Seconds >= 10) {
     Timer.text = (Minutes.ToString() + ":" + Seconds.ToString());
   }
  }
 }

And not to touch the onTrigger function. And second solution, use function StopAllCoroutines() instead of StopCoroutine in you OnTrigger:

 void OnTriggerEnter (Collider other) {
  if(other.gameObject.tag == "Pickup") {
   other.gameObject.SetActive (false);
   CubesCollected++;
   CubeCounter.text = "Cubes Collected: " + CubesCollected.ToString () + " / " + TotalCubes.ToString ();
   if(CubesCollected == TotalCubes) {
    StopAllCoroutines(); // I change this line
    WinText.text = ("Challenge Completed");
   }
  }
 }

I hope it will help you.